!standard 13.1(23) 09-06-01 AI05-0155-1/01 !class binding interpretation 09-06-01 !status work item 09-06-01 !status received 09-04-07 !priority Medium !difficulty Medium !qualifier Omission !subject 'Size clause on type with nonstatic bounds !summary ** TBD ** !question What does "any value of the subtype" mean when the bounds of the subtype aren't known at compile time? package Pak1 is type Integer_32 is range -2**31 .. 2**31-1; procedure Proc (Low, High : Integer_32); end Pak1; package body Pak1 is procedure Proc (Low, High : Integer_32) is type T is new Integer_32 range Low .. High; for T'Size use 16; -- Legal? begin null; end Proc; end Pak1; Is the 'Size clause legal, requiring a check at runtime to make sure there's enough space given the actual values of Low and High; or is it illegal? !recommendation (See Summary.) !wording ** TBD ** !discussion 13.1(23) says that there are no requirements to support representation items on composite types with non-static constraints. But that leaves such items supported for all elementary types, and covered by the recommended level of support. That means, for instance, that supporting specifying of 'Size for discrete and fixed point types wuth dynamic constraints is required so long as the value is large enough to allow "any value of the subtype". There seems to be four possible solutions to this problem: (1) Allow any reasonable value for 'Size, and require a runtime check that it fit based on the actual bounds. (similarly for record representation component clauses.). This is clearly the most flexible solution, but it adds runtime overhead and surely would need wording to define the needed check. (2) Remove "composite" from 13.1(23). This would put all subtypes on an equal footing here, and would match the Ada 83 rules. But it seems clear that the Ada 9x team intended this as a language change - it would be hard to rewrite this text and accidentally insert "composite"! Unfortunately, they did not document this as either an extension to Ada83 or wording change from Ada83, so we don't know for sure. (3) Add wording to to exclude dynamically constrained discrete and fixed point types from the requirements of "recommended level of support" for subtypes and record representation component clauses. This would not be substansively different than (2), other than continuing to allow specification of non-confirming alignments for such subtypes. And this would require more complex wording in a number of places. (4) Actually define what "any value of the subtype" means for dynamically constrained subtypes. We could define it to use whatever static bound information is known about the bounds. (Perhaps as a Ramification and "Honest" AARM note rather than actual language text.) However, we need to be careful to deal with cases where bounding information comes from the bound expressions as well as from the parent subtype. For instance: package Pak2 is type Integer_32 is range -2**31 .. 2**31-1; subtype Sub is Integer_32 range -100 .. 100; procedure Proc (Low, High : Sub); end Pak2; package body Pak2 is procedure Proc (Low, High : Sub) is type T is new Integer_32 range Low .. High; for T'Size use 16; -- Legal? begin null; end Proc; end Pak2; Requiring support for this case is surely more complex than simply looking at the "narrowest" static bounds of an ancestor subtype. (Compilers often use "narrowest bound" information for eliminating range checks, so that is a common operation.) We would also need to explain what "any value" means when there is no information about the parent subtype, as in the case of generic formal types: generic type Disc is (<>); Low, High : Disc; package Pak3 is type New_Disc is range Low .. High; for New_Disc'Size use 16; -- Legal? Rechecked? end Pak3; type Integer_16 is range -2**16 .. 2**16-1; for Integer_16'Size use 16; package New_Pak3 is new Pak3 (Integer_16, 0, 10_000); -- Legal? None of these solutions appears particularly appealing. --!corrigendum 13.1(23) !ACATS Test This a permission not to support something, so it is not testable. !appendix !topic 'Size clause on type with nonstatic bounds !reference 13.1(12) !from Adam Beneschan 09-04-07 !discussion 13.1(12): "A representation item that specifies the Size for a given subtype, or the size or storage place for an object (including a component) of a given subtype, shall allow for enough storage space to accommodate any value of the subtype." What does "any value of the subtype" mean when the bounds of the subtype aren't known at compile time? package Pak1 is type Integer_32 is range -2**31 .. 2**31-1; procedure Proc (Low, High : Integer_32); end Pak1; package body Pak1 is procedure Proc (Low, High : Integer_32) is type T is new Integer_32 range Low .. High; for T'Size use 16; -- LEGAL? begin null; end Proc; end Pak1; Is the 'Size clause legal, requiring a check at runtime to make sure there's enough space given the actual values of Low and High; or is it illegal? package Pak1 is type Integer_32 is range -2**31 .. 2**31-1; subtype Sub is Integer_32 range -100 .. 100; procedure Proc (Low, High : Sub); end Pak1; package body Pak1 is procedure Proc (Low, High : Sub) is type T is new Integer_32 range Low .. High; for T'Size use 16; -- LEGAL? begin null; end Proc; end Pak1; What about this one? Ada 83 disallowed 'Size clauses on types with non-static constraints, but I don't see this restriction anywhere in Ada 95 or Ada 2005. GNAT rejects both, by the way, saying that a minimum size of 32 is required. **************************************************************** From: Randy Brukardt Date: Wednesday, April 8, 2009 1:24 PM ... > What does "any value of the subtype" mean when the bounds of the > subtype aren't known at compile time? The rules requiring staticness were moved to "Recommended Level of Support". Specifically, 13.1(22) and 13.1(23) say that non-static stuff doesn't need to be supported. But there seems to be an intentional hole for elementary types. Why that is is totally unclear to me, as it either requires ridiculous implementation hand-stands or is totally pointless. (The only representation clause that could reasonably required for such a type is a confirming one, which by itself doesn't seem useful enough to require.) Because of that supposedly intentional hole, we definitely do need to mention "non-static" constraints in the recommended level of support for 'Size. (Or we need to remove the hole by deleting "composite" from 13.1(23); that would be easier but would deal with more than the immediate problem). Probably, there should be an extra bullet in 13.3(56.1-3): An implementation need not support a non-confirming Size clause for a type with non-static constraints. That would leave examples like yours completely implementation-defined (without banning them outright). Something similar ought to be done for elementary components of a subtype with non-static constraints in a record representation clause (it has the same issues since the number of bits needed is not known at compile-time). ****************************************************************