Version 1.1 of ai12s/ai12-0226-1.txt

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

!standard 3.3(11.1/3)          17-04-18 AI12-0226-1/01
!standard 3.3(12)
!standard 3.3(21/3)
!standard 3.3(22)
!standard 3.3(23.7/3)
!standard 3.10(9/3)
!standard 4.6(58.1/4)
!standard 4.6(58.4/4)
!class Amendment 17-04-18
!status work item 17-04-18
!status received 17-03-23
!priority Low
!difficulty Easy
!subject Generalize expressions that are objects
!summary
Value conversions represent objects in the same way as a function call represents an object. A parenthesized expression of an object represents an object.
!problem
After various changes in Ada 95 and Ada 2012, there is no rhyme nor reason to the difference between expressions that represent objects and those that represent values. Consider the following:
Limit : constant := 10; Max : constant Natural := 10;
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 -- 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 : Natural renames Natural'(Max);-- Legal, object. Ren7 : Natural renames Natural'(Limit); -- Illegal, not object. (A named -- number is not an object.) Ren8 : Natural renames Max; -- Legal, object. Ren9 : Natural renames (Max); -- Illegal, not object. (A parenthesized -- expression is not an object, -- regardless of what is -- parenthesized.) RenA : Boolean renames Boolean'(A and B); -- Legal, object. ("and" is -- a function.) RenB : Boolean renames Boolean'(A and then B); -- Illegal, not object -- ("and then" is an operation, not a function.)
How many of you got this right? We should at least fix the worst warts of this list.
!proposal
(See Summary.)
!wording
[The definition of object:]
Add after 3.3(11.1/3):
* a value conversion;
Modify 3.3(12):
* a component, slice, {parenthesized expression}, or view conversion
of another object.
[Note: "expression" of parenthesized expression is in the syntax font.]
[The definition of constants:]
Modify 3.3(21/3):
* the object denoted by a {value conversion, }function_call{,} or
[an] aggregate;
Modify 3.3(22/3):
* a selected_component, indexed_component, slice, {parenthesized expression},
or view conversion of a constant.
[The definition of known to be constrained:]
Modify 3.3(23.7/3):
* it is part of the object denoted by a {value conversion, }function_call{,}
or aggregate; or
{* it is a parenthesized expression where the expression denotes a view of a
composite object that is known to be constrained;}
Modify 3.10(9/3):
A view of an object is defined to be aliased if it is defined by an object_declaration, component_definition, parameter_specification, or extended_return_object_declaration with the reserved word aliased, or by a renaming of an aliased view. In addition, the dereference of an access-to-object value denotes an aliased view, as does a view conversion (see 4.6) of an aliased view. {A parenthesized expression where the expression denotes an aliased view is an aliased view.} The current instance of an immutably limited type (see 7.5) is defined to be aliased. Finally, a formal parameter or generic formal object of a tagged type is defined to be aliased. [Aliased views are the ones that can be designated by an access value.]
Modify 4.6(58.1/4):
Evaluation of a value conversion [of a composite type] 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.4/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 (as an elementary type cannot be controlled).
!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 also make the result of a parenthesized object an object, so that parenthesized expressions and qualified expressions have the same static semantics.
The other kinds of expressions that are not objects are:
* numeric literals;
* the literal null;
* named numbers;
* membership tests;
* short circuit control forms;
* attributes that are not defined as functions.
We considered defining everything to be an object, but it seemed strange that a literal like 12 or null would be an object. Named numbers are intended to work like literals. There doesn't seem to be much use to renaming boolean expression, so we didn't change either of those, either. And changing a number of attribute definitions seemed like dimishing returns.
!ASIS
[Not sure. It seems like some new capabilities might be needed for operators, but I didn't check - 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
> <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