Version 1.1 of acs/ac-00148.txt

Unformatted version of acs/ac-00148.txt version 1.1
Other versions for file acs/ac-00148.txt

!standard 13.3(16)          07-10-23 AC95-00148/01
!class confirmation 07-10-23
!status received no action 07-10-23
!status received 07-09-25
!subject 'Address of anonymous objects and tasks?
!summary
!appendix

!topic 'Address of anonymous objects and tasks?
!reference 13.3(16)
!from Adam Beneschan 07-09-25
!discussion

This is a question about Implementation Advice, so perhaps it's not
quite as important to nail down the exact meaning as, say, a Legality
Rule; but it's still important to know what users who write portable
code have a right to expect.

Anyway, 13.3(16) says: "X'Address should produce a useful result if X
is an object that is aliased or of a by-reference type, or is an
entity whose Address has been specified."

The return object created as the result of evaluating a function call
is an object (3.3(10)).  So suppose a function Func returns a tagged
type or some other by-reference type.  Is it recommended that
implementations should support this (i.e. return a useful value)?

    Addr := Func(1)'Address;

It would seem silly to require this, since the anonymous object
created by Func is possibly going to cease to exist after this
statement.  I don't know what the Implementation Advice would mean in
this case---does the compiler have to ensure that this anonymous
object is generated in a place where it will never disappear?

Or should wording be added to 13.3(16) to clarify that that kind of
object isn't meant here?  (Maybe a "To be honest" in the AARM would be
enough?)

Secondary question: A task type is a by-reference type, but is it
really intended that X'Address "should produce a useful result" if X
is a task object?  Unlike other objects, which contain "data" of an
Ada type (even protected objects usually carry some sort of data), a
task object isn't really "data" and the 'Address concept doesn't
really make intuitive sense.  For many implementations it may make
sense to define 'Address in a way peculiar to that implementation, but
it doesn't seem that the RM ought to be suggesting that 'Address has
to be useful in all implementations.

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

From: Randy Brukardt
Sent: Tuesday, October 16, 2007  2:15 AM

I just happened to notice this rather old question...

> Anyway, 13.3(16) says: "X'Address should produce a useful result if X
> is an object that is aliased or of a by-reference type, or is an
> entity whose Address has been specified."

My understanding of the intent of this rule is that 'Address should work
(that is, return a real machine address) when 'Access is allowed. OTOH, when
'Access is not allowed, then the compiler can allocate the object in a way
that 'Address doesn't work (for instance, in a register). That's what the
AARM notes following 13.3(16) say.

> The return object created as the result of evaluating a function call
> is an object (3.3(10)).  So suppose a function Func returns a tagged
> type or some other by-reference type.  Is it recommended that
> implementations should support this (i.e. return a useful value)?
>
>     Addr := Func(1)'Address;
>
> It would seem silly to require this, since the anonymous object
> created by Func is possibly going to cease to exist after this
> statement.  I don't know what the Implementation Advice would mean in
> this case---does the compiler have to ensure that this anonymous
> object is generated in a place where it will never disappear?

No, of course not. The IA says nothing about the lifetime of the object,
only that you get a real machine address when you ask for it on the object.
Just because the IA requires a "useful result" at the point of the 'Address
doesn't mean that the object won't disappear later. Indeed, that is one of
the reasons for this advice: to make it clear that compilers don't have to
bend over backwards to try to keep objects that are referenced with 'Address
in memory.

Note that this can be a useful capability, for instance if it is used inside
of Adjust for the assignment of a function:
     Obj := Func(1);

Similarly, the lifetime of the object can be varied easily:

     Obj : T renames Func(1);
     Addr := Obj'Address; -- The IA says this should work.

> Or should wording be added to 13.3(16) to clarify that that kind of
> object isn't meant here?  (Maybe a "To be honest" in the AARM would be
> enough?)

I suppose a note that nothing about this advice is intended to change the
lifetime of an object would be OK to add to the AARM. But it doesn't seem
very necessary to me; 'Address doesn't have any effect on the semantics of
the object (I hope).

> Secondary question: A task type is a by-reference type, but is it
> really intended that X'Address "should produce a useful result" if X
> is a task object?  Unlike other objects, which contain "data" of an
> Ada type (even protected objects usually carry some sort of data), a
> task object isn't really "data" and the 'Address concept doesn't
> really make intuitive sense.  For many implementations it may make
> sense to define 'Address in a way peculiar to that implementation, but
> it doesn't seem that the RM ought to be suggesting that 'Address has
> to be useful in all implementations.

I don't think 'Address is very useful for reading in Ada 95 programs anyway;
it's important to be able to specify it, but you are better off using
'Access rather than 'Address when reading.

Thus, I'd expect the rules for 'Address and 'Access to be essentially the
same. It seems odd that tasks are required to be allowed for 'Address but
'Access isn't allowed (without an explicit aliased declaration). And I doubt
that there is anything "useful" about whatever the result would be. Still,
it seems insufficiently broken; I don't know of any real problem making task
objects act as if they are aliased - it might be a bit less efficient than
necessary, but you're not likely to have millions of tasks.

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

From: Adam Beneschan
Sent: Wednesday, October 17, 2007 11:10 AM

...
> > It would seem silly to require this, since the anonymous object
> > created by Func is possibly going to cease to exist after this
> > statement.  I don't know what the Implementation Advice would mean in
> > this case---does the compiler have to ensure that this anonymous
> > object is generated in a place where it will never disappear?
>
> No, of course not. The IA says nothing about the lifetime of the object,
> only that you get a real machine address when you ask for it on the object.
> Just because the IA requires a "useful result" at the point of the 'Address
> doesn't mean that the object won't disappear later.

OK, I can see how the result of 'Address could be useful, if only for
a brief period:

    X := Func1 (Func2(Param)'Address);

where Func1's parameter is a System.Address.  It looks like the rules
require the anonymous object returned by Func2 to stay around long
enough for Func1 to finish executing, even though all we do with the
anonymous object is take its 'Address.

> > Secondary question: A task type is a by-reference type, but is it
> > really intended that X'Address "should produce a useful result" if X
> > is a task object?  Unlike other objects, which contain "data" of an
> > Ada type (even protected objects usually carry some sort of data), a
> > task object isn't really "data" and the 'Address concept doesn't
> > really make intuitive sense.  For many implementations it may make
> > sense to define 'Address in a way peculiar to that implementation, but
> > it doesn't seem that the RM ought to be suggesting that 'Address has
> > to be useful in all implementations.
>
> I don't think 'Address is very useful for reading in Ada 95 programs anyway;
> it's important to be able to specify it, but you are better off using
> 'Access rather than 'Address when reading.
>
> Thus, I'd expect the rules for 'Address and 'Access to be essentially the
> same.

My objection to this is that the language doesn't specify how 'Access
is implemented; there's no requirement (that I know of) that it refer
to a memory address of any sort.  The result of 'Address, however, is
a System.Address, which is supposed to be a reference to storage.
This means that even the fact that 'Access may be allowed doesn't mean
that it's possible to return a meaningful value for 'Address.

One can envision an implementation of Ada tasking in which the memory
accessible to the environment task does not contain any control
information about other tasks, and all task operations are done
through the OS.  An 'Access to such a task type (if there is a
declared task type) could conceivably be implemented as a process ID
or some other sort of handle used in OS calls.  (An instantiation of
System.Address_To_Access_Types for such an access type would of course
be prohibited, as allowed by 13.7.2(6).)  I don't see anything that
would prevent such an implementation, nor do I see a reason why a
process ID value would need to be in memory at any point---it could be
held in a register.  But if nothing is ever stored in actual storage
that the environment task could access, what would 'Address return?
Whatever it returned, it wouldn't be "useful".

I'm not sure whether this might apply to protected types, too.
Probably not, since components declared in the private part have to be
put somewhere.

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

From: Tucker Taft
Sent: Wednesday, October 17, 2007 11:21 AM

Since tasks can have discriminants, I don't see how
you could ever *not* have a task object in user space.
The 'Address of a task would typically be the address
of this task "object," which I agree might be no
more than a handle, plus (copies of) the discriminants.

Have you ever seen an Ada implementation that did
*not* have some kind of task object in user space?
Or are we just talking hypotheticals here?  If the latter,
I have some projects here you could work on if you
have too much free time on your hands... ;-) ;-)

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

From: Adam Beneschan
Sent: Wednesday, October 17, 2007  1:52 PM

> Since tasks can have discriminants, I don't see how
> you could ever *not* have a task object in user space.
> The 'Address of a task would typically be the address
> of this task "object," which I agree might be no
> more than a handle, plus (copies of) the discriminants.

But the compiler would only have to do this for task types with
discriminants.  The compiler would know which task types don't have
discriminants, and it seems possible to me (in theory) that a compiler
may want to optimize things for tasks that don't.


> Have you ever seen an Ada implementation that did
> *not* have some kind of task object in user space?
> Or are we just talking hypotheticals here?

I think that our compiler supports a mode that we implemented for a
customer some years ago, where the kinds of task operations were
severely restricted (parameterless entries only, no SELECT statement,
etc.).  I don't know whether this allowed us to eliminate the entire
task control block, or just part of it.  We probably still had some
sort of object in memory---it was needed for our implementation of
full Ada tasking, and there wasn't a need change our implementation
that drastically for our customer.

So it's almost real but still sort of hypothetical, or something.
Nevertheless, it still seems like a reasonable implementation to
implement (discriminant-less) tasks with no memory usage, and I don't
see a particular reason why the RM would need to prevent such an
implementation from being done because of an Implementation Advice
that nobody would take advantage of---what possible reason would
someone want to take the 'Address of a task in portable Ada code?  (I
can only envision someone using the 'Address of a task if the
application is geared to a particular implementation, and the
programmer has intimate knowledge of the implementation details.)  I
don't see any cost, other than administrative costs (which I know you
and Randy would bear and I wouldn't :)), to adding "other than a task"
to this section of the RM, so that implementations (real or
hypothetical) that for some reason found it tricky to generate an
'Address for a task wouldn't have to.


> If the latter,
> I have some projects here you could work on if you
> have too much free time on your hands... ;-) ;-)

Sure, I can take on those projects if you're willing to track down our
customers' problems for us.  :) :) :)

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


Questions? Ask the ACAA Technical Agent