!standard 3.3(11.1/3) 18-06-10 AI12-0226-1/03 !standard 3.3(21.1/3) !standard 3.3(23.8/5) !standard 4.6(58.1/4) !standard 4.6(58.3/4) !class Amendment 17-04-18 !status Amendment 1-2012 18-07-10 !status ARG Approved 7-1-2 18-06-23 !status work item 17-04-18 !status received 17-03-23 !priority Low !difficulty Easy !subject Make objects more consistent !summary A value conversion of an object is an object in order to be consistent with a qualified expression. !problem Ada 2012 made a qualified expression a "name", and a qualified expression of an object is an object. This created an unusual situation where a single character makes a difference between constructs usually considered equivalent: Max : constant Natural := 10; Ren1 : Natural renames Max; -- Legal. Ren2 : Natural renames Natural'(Max);-- Legal, object. Ren3 : Natural renames Natural(Max); -- Illegal, not object. (A value -- conversion is not an object.) We can make qualified expression and value conversion be more regular. !proposal (See Summary.) !wording [The definition of object:] Modify 3.3(11.1/3): * a {value conversion or }qualified_expression whose operand denotes an object; [The definition of constants:] Modify 3.3(21.1/3): * the result of evaluating a {value conversion or }qualified_expression; [The definition of known to be constrained:] Modify 3.3(23.8/5): * it is a {value conversion or }qualified_expression where the operand denotes a view of a composite object that is known to be constrained; or Modify 4.6(58.1/4): Evaluation of a value conversion [of a composite type]{of an object} either creates a new anonymous object Redundant[(similar to the object created by the evaluation of an aggregate or a function call)] or yields a new view of the operand object without creating a new object: Add after 4.6(58.3/4): If the target type is an elementary type, then a new object is created; Add after AARM 4.6(58.b.1/4): AARM Implementation Note: The new temporary object need not be materialized in most cases; it should be handled like the return object of a predefined operator. Generally, whether the object exists can only be detected if it is renamed (unless the type is controlled). AARM Discussion: This set of rules does not apply in those cases where the operand is not an object (such as a value conversion of a named number); in such cases, the result isn't an object, so it isn't necessary to describe what that means. The rules cover all value conversions of composite types (since there aren't any separate values of composite types). !discussion A value conversion looks much like a function call and similar to a qualified expression, both of which represent objects (the latter only if the expression is already an object). Therefore, we treat it consistently and make it an object as well. Note that most of the needed wording was already added by AI12-0027-1. We expect that compilers will materialize this temporary object only when it is required, as is typically done for the result object of predefined operators. We made value conversions consistent with qualified expressions in the wording above, but we could have made them consistent with function calls instead. The wording differences are minimal (drop "new value," and the associated AARM discussion from 4.6(58.1/4), and put "value conversion" with function call rather than qualified expression in 3.3 [two places]). The difference can be seen when renaming uses of named numbers: Limit : constant := 12; function Func (A : Natural) return Natural ... RenA : Natural renames Natural'(Limit); -- Illegal, not object. RenB : Natural renames Natural(Limit); -- (A) RenC : Natural renames Func(Limit); -- OK, object by Ada 95. (A) is illegal with the wording as suggested, and would be legal with the more general wording mentioned here. With either wording in this AI, all three would be legal if Limit had been a constant object (if a subtype had been given in the declaration). We also considered making the result of a parenthesized object an object, so that parenthesized expressions and qualified expressions have the same static semantics. However, since a parenthesized object should be considered a constant and is not syntactically a name, there does not appear to be any places where such a construct could be used. A more general fix would be to eliminate the distinctions between "name" and "expression" as well as "object" and "value", but that would require extensive surgery to the Standard, so it is is not simple and is covered in a separate AI - AI12-0270-1. !corrigendum 3.3(11/3) @drepl @xbullet whose operand denotes an object;> @dby @xbullet whose operand denotes an object;> !corrigendum 3.3(21/3) @drepl @xbullet;> @dby @xbullet;> !corrigendum 3.3(23.7/3) @dinsa @xbullet or @fa; or> @dinst @xbullet where the operand denotes a view of a composite object that is known to be constrained; or> !corrigendum 4.6(58.1/4) @drepl Evaluation of a value conversion of a composite type either creates a new anonymous object (similar to the object created by the evaluation of an @fa or a function call) or yields a new view of the operand object without creating a new object: @dby Evaluation of a value conversion of an object either creates a new anonymous object (similar to the object created by the evaluation of an @fa or a function call) or yields a new view of the operand object without creating a new object: !corrigendum 4.6(58.3/4) @dinsa @xbullet @dinst @xbullet !ASIS [Probably not, but not certain - Editor.] !ACATS test An ACATS C-Test is needed to check that the new capabilities are supported. !appendix [The following thread is forked from the discussion filed in AI12-0225-1.] From: Randy Brukardt Sent: Thursday, March 23, 2017 7:46 PM > I just think the distinction between objects and values is lost on > many users, and we allow 'Last, 'First, etc., on names that denote > array values, so why not allow 'Image on names that denote scalar > values. I tend to agree with this sentiment. Particularly the first part, because given the various changes in Ada 95 and Ada 2012, that distinction is lost on many Ada language lawyers as well. I for one can detect no reason for what is an object and what is a value in Ada 2012. More in a moment. ... > X'Image is meant to be equivalent to > 'Image(X), and clearly in this latter form, X can denote a > value rather than an object. If we restrict a name in some context to > denote an "object," it really ought to be something that relies on a > memory cell of some sort to exist, such as 'Address, 'Size, or > 'Alignment. But in Ada 2012, almost everything is an object. The only expressions that are never objects in Ada 2012 + TC1 are numeric and access literals, named numbers, value conversions of elementary types, membership tests, short circuit control forms, some attributes, and parenthized expressions. Why those particular things are values, but things like logical operators, qualifications of objects, and even the discrete Pos attribute deliver objects is beyond my understanding. Consider object renaming, which like the name says, requires an object. Ren1 : Natural renames Natural'(1); -- Illegal, not object. Ren2 : Natural renames Natural'(+1); -- Legal, "+1" is equivalent to a function call "+"(1), and the -- result object of a function call is clearly an object [3.3(13)]. Ren3 : Natural renames Natural(+1); -- Illegal, not object (value conversion isn't an object). Ren4 : Natural renames Natural'First;-- Illegal, not object. Ren5 : Natural renames Natural'Val(1); -- Legal, object. (Val denotes a function.) Ren6 : Boolean renames Boolean'(A and B); -- Legal, object. ("and" is a function.) Ren7 : Boolean renames Boolean'(A and then B); -- Illegal, not object ("and then" is an operation, not a function.) I have to wonder if it would make more sense to clean up this mess rather than bothering to change any attributes. After all, the fact that function calls return objects don't suddenly make compilers stick every scalar intermediate value into memory -- a compiler only materializes the return object if it matters (as in the legal renamings above). In particular, value conversion of composite types now (optionally in some cases) creates an anonymous object, that was to fix a problem someone reported caused by the accessibility of components of by-reference types when the actual is a value conversion. (One guess as to which someone would care about that case.) A tiny bit of additional wording and we could have an object for all value conversions. (Doing that alone would get rid of the Image case that I was most concerned about - the bizarre difference between Ren2 and Ren above.) ... **************************************************************** From: Jeff Cousins Sent: Tuesday, March 28, 2017 8:21 AM > Consider object renaming, which like the name says, requires an object. > > Ren1 : Natural := Natural'(1); -- Illegal, not object. > Ren2 : Natural := Natural'(+1); -- Legal, "+1" is equivalent to a function call "+"(1), and the > -- result object of a function call is clearly an object [3.3(13)]. This is probably worth a new thread. It's certainly the kind of thing that gets new Ada programmers tearing their hair out. ****************************************************************