Version 1.1 of acs/ac-00173.txt

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

!standard 10.2.1(5-9)          09-06-01 AC95-00173/01
!class confirmation 09-06-01
!status received no action 09-06-01
!status received 09-02-27
!subject Preelaboration rules need loosening?

!topic Preelaboration rules need loosening?
!reference 10.2.1(5-9)
!from Adam Beneschan 09-02-27

I'm looking at a GNAT implementation of Ada.Exceptions, in  I
think it's from 2007 (I don't know if there's a later version around).  The
interesting parts of this are:

    package Ada.Exceptions is

       pragma Preelaborate_05;


       subtype Code_Loc is System.Address;
       Null_Loc : constant Code_Loc := System.Null_Address;

    end Ada.Exceptions;

Preelaborate_05 is GNAT's own pragma, I realize, but the definition of
Ada.Exceptions indicates that the package must be preelaborable (11.4.1(2)), so
I think we can assume that the package is supposed to be preelaborable.

But it doesn't look like it follows the rules for that.  10.2.1(8) says that one
of the things that makes a construct non-preelaborable is the evaluation of a
_primary_ that is the _name_ of an object, unless the _name_ is a static
expression (or statically denotes a discriminant...).  Here, the elaboration of
the constant declaration causes the evaluation of System.Null_Address, which is
the name of a constant object in System; and it's not a static expression since
it's a deferred constant (since GNAT follows the Implementation Advice that
System.Address is a private type).  (AARM 4.9(24.a)) So I think this declaration
makes Ada.Exceptions non-preelaborable.  (The full view of Null_Occurrence also
includes a component whose elaboration requires evaluating System.Null_Address.)

My point isn't to say "Gotcha" about GNAT doing something illegal, but to whine
that what they're doing seems like a reasonable thing to do in a preelaborable
package, but it appears that the rules don't allow this.  I don't know how this
would be fixable, except to provide a pragma that a programmer could apply to a
deferred constant saying "This will be a static constant, or a preelaborable
constant", or something like that, and then requiring that the full constant be
static or preelaborable if this pragma is used.  Then 10.2.1(8) would allow the
evaluation of names that denote such constants.

(Please note that in the case of System.Null_Address, the full constant
declaration in GNAT's system package is a static expression, since it's 0; but
if System.Address is a two-component record, as in a case I have to deal with,
Null_Address could not be a static constant since it's not a scalar.  So a rule
that depends on something being a "static constant" may not be good enough.)


From: Adam Beneschan
Date: Friday, February 27, 2009  1:55 PM

Actually, on further reflection, is there any reason for 10.2.1(8) not to allow
a name that denotes *any* constant?  Any constant object that is named must be
declared in another preelaborable package, and thus its value must satisfy the
rules in 10.2.1(5-9).  So it seems that, at least, if a constant's (full)
declaration is preelaborable, and another object declaration uses that
constant's value as its own initial value, or as a subcomponent of the initial
value, then that shouldn't prevent the second object declaration from
preelaborable also.  (I realize that the constant name could be evaluated in
other contexts besides as an initial value or subcomponent of an initial value
of an object, and maybe those cause problems---I don't know.)


Questions? Ask the ACAA Technical Agent