!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". ****************************************************************