Version 1.1 of ai12s/ai12-0356-1.txt
!standard 13.11.4(4/3) 20-01-12 AI12-0356-1/01
!standard 13.11.4(5/3)
!class binding interpretation 20-01-12
!status work item 20-01-12
!status received 19-10-11
!priority Low
!difficulty Easy
!qualifier Omission
!subject Root_Storage_Pool_With_Subpools should have Preelaborable_Initialization
!summary
Root_Storage_Pool_With_Subpools has Preelaborable_Initialization.
!question
Type Root_Storage_Pool_With_Subpools doesn't have a
Preelaborable_Initialization pragma. That prevents creation of such pool
objects at library level in Preelaborate units.
Is this intentional? (No.)
!recommendation
(See Summary.)
!wording
Modify 13.11.4(4/3):
type Root_Storage_Pool_With_Subpools is
abstract new Root_Storage_Pool with private;
pragma Preelaborable_Initialization (Root_Storage_Pool_With_Subpools);
Modify 13.11.4(5/3):
type Root_Subpool is abstract tagged limited private;
pragma Preelaborable_Initialization (Root_Subpool);
!discussion
It seems that most pool objects will be declared at library level. Thus,
we need to require Preelaborable_Initialization, otherwise we have a
preelaborable package that is hard to use in preelaborable units.
Note that Root_Subpool also should have Preelaborable_Initialization, for
similar reasons.
!ASIS
No ASIS effect.
!ACATS test
!appendix
!topic Add Preelaborable_Initialization to Root_Storage_Pool_With_Subpools
!reference Ada 2012 RM13.11.4(4/3)
!from Maxim Reznik 19-10-11
!keywords storage_pool subpool
!discussion
Type Root_Storage_Pool_With_Subpools doesn't have
Preelaborable_Initialization aspect. This prevent usage of its
implementations in a Preelaborate units.
Is it intentional or just missed?
****************************************************************
From: Randy Brukardt
Sent: Friday, October 11, 2019 1:18 PM
AI12-0235-1 changed the categorization of Root_Storage_Pool to Pure. I believe
that types from Pure units are always allowed in preelaborable units (the
pragam Preelaborable_Initialization isn't needed for such types). [If that's
not true, there's a number of language-defined units that are missing that
pragma.]
****************************************************************
From: Randy Brukardt
Sent: Friday, October 11, 2019 1:23 PM
Ignore my first answer, I didn't read close enough (I answered about the root
package and not the subpool packages).
I believe it is intentional; the type necessarily includes components for
handling subpools and we didn't want to restrict how those are implemented.
But it's very possible that it was only intentional from me and wasn't
discussed by the entire ARG. (And it's also possible that I'm confusing it
with something else. :-)
****************************************************************
From: Maxim Reznik
Sent: Wednesday, November 20, 2019 3:06 AM
Can you provide an example where implementation requires this type to be
non-preelaborable?
Consequence of this decision is very heavy: any unit that reference an access
type intended to be allocated in a subpool can't be Preelaborable. Also all
units in the closure of dependencies.
****************************************************************
From: Randy Brukardt
Sent: Wednesday, November 20, 2019 6:01 PM
> Can you provide an example where implementation requires this type to
> be non-preelaborable?
It's more about not fencing in implementors; others have a lot of different
ways of building things and it seems that many of them would be problematic.
I find it extremely difficult to build efficient preelaborable libraries, as
the usual ways to get around preelaborable restrictions are a lot of
access-to-subprogram parameters and conditional initialization (that is,
initialization occurs on the first use of a package) -- these all add
overhead.
> Consequence of this decision is very heavy: any unit that reference an
> access type intended to be allocated in a subpool can't be
> Preelaborable. Also all units in the closure of dependencies.
IMHO, preelaboration is almost never possible -- there's always something that
is required that can't be preelaborable. In particular, the inability to use
Calendar and Text_Io means no timing and no debugging text. One almost always
has to develop such things without the categorization and then add it later --
but that often leads to a design that doesn't work with the pragma. (And it is
counter to my personal standard of leaving the debugging code in modules for
use when a bug shows up in production.)
Moreover, outside of distribution (which is only supported by GNAT anyway, so
completely not portable, and in any case, can't use storage pools or most
access types), there is no real value to preelaboration. Compilers don't
intentionally make their code worse for no reason, so any of the code
improvements that are tied to C.4 are almost certainly going to happen whether
or not the unit is categorized.
To me, the Pure and Preelaborate categorizations are a failure that aren't
worth worrying about much going forward. The Global aspect will provide the
important part of the categorizations with the pain being much more localized
(to a single routine). Global also eliminates most of the "end-runs" that
prevent the categorizations from being useful for parallelism and
optimization. Ergo, categorizations are something that I'd leave out of
"Better Ada".
****************************************************************
Questions? Ask the ACAA Technical Agent