# Version 1.3 of ai12s/ai12-0226-1.txt

Unformatted version of ai12s/ai12-0226-1.txt version 1.3
Other versions for file ai12s/ai12-0226-1.txt

!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
!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:
If the target type is an elementary type, then a new object is created;
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)
Replace the paragraph:
• a qualified_expression whose operand denotes an object;
by:
• a value conversion or qualified_expression whose operand denotes an object;
!corrigendum 3.3(21/3)
Replace the paragraph:
• the result of evaluating a qualified_expression;
by:
• the result of evaluating a value conversion or qualified_expression;
!corrigendum 3.3(23.7/3)
Insert after the paragraph:
• it is part of the object denoted by a function_call or aggregate; or
the new paragraph:
• 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
!corrigendum 4.6(58.1/4)
Replace the paragraph:
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 aggregate or a function call) or yields a new view of the operand object without creating a new object:
by:
Evaluation of a value conversion of an object either creates a new anonymous object (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:
!corrigendum 4.6(58.3/4)
Insert after the paragraph:
• If the target type is an array type having aliased components and the operand type is an array type having unaliased components, then a new object is created;
the new paragraph:
• If the target type is an elementary type, then a new object is created;
!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
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
> <type-of-X>'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.

****************************************************************

```

Questions? Ask the ACAA Technical Agent