CVS difference for ais/ai-00109.txt

Differences between 1.3 and version 1.4
Log of other versions for file ais/ai-00109.txt

--- ais/ai-00109.txt	1999/11/29 21:14:21	1.3
+++ ais/ai-00109.txt	2004/04/30 02:35:37	1.4
@@ -1,5 +1,6 @@
-!standard 13.03    (55)                               99-11-29  AI95-00109/07
+!standard 13.03    (55)                               04-04-20  AI95-00109/08
 !class binding interpretation 96-04-04
+!status deleted 04-04-20
 !status work item 98-04-01
 !status ARG Approved (subject to letter ballot)  7-0-3  97-11-14
 !status work item (letter ballot was 4-4-3) 96-10-03
@@ -9,3499 +10,19 @@
 !reference AI95-00051
 !priority High
 !difficulty Hard
-!subject Size and Alignment Attributes for Subtypes
+!subject (Deleted)
 
 !summary
 
-This AI addresses issues related to Size and Alignment attributes for
-subtypes.  For Size and Alignment of objects, see AI95-00051.
+This AI has been combined into AI95-00051 and AI95-00291.
 
-A non-first subtype inherits each subtype-related aspect (namely, Size
-and Alignment) from the first subtype, if the two subtypes are
-statically matching.
-
-Recommended Level of Support:
-
-    For a packed record or array type, the Size of the first subtype
-    should reflect the requirements of RM-13.2(7-9), except that if the
-    record or array does not fit in a single word, the Size may be
-    rounded up, but not past the next word boundary.
-
-    13.3(31) is replaced by:
-
-    For a subtype that satisfies 13.1(23), the implementation need not support
-    an Alignment clause unless:
-
-        - For record types and type extensions: The size in storage elements
-          is a multiple of the Alignment.
-
-        - For arrays: This advice is applied recursively to the component
-          subtype.
-
-        - For a signed integer subtype, the Alignment is less than or equal
-          to that of the largest signed integer type supported by the
-          implementation.
-
-        - For a modular integer subtype, the Alignment is less than or equal
-          to that of the largest modular type supported by the implementation.
-
-        - For an enumerated subtype, the Alignment is less than or
-          equal to that of the largest signed integer type, or the largest
-          modular type, which ever is least aligned.
-
-        - For fixed point, floating point, access, protected and task subtypes:
-          the Alignment is what would have been chosen by default.
-
-Implementation Advice:
-
-    If a type obeys the rules for well-defined unchecked conversion
-    given in 13.9(17), then the implementation should support a Size
-    clause that is the same as what the implementation would have chosen
-    by default.
-
 !question
 
-The wording of 13.2(7-9) seems vague.  For example, it refers to "packed
-as tightly as possible".  What does this imply about the Size of a
-packed array or record?
-
-Suppose a subtype S statically matches a first subtype T, and that the
-Size of T has been specified ("for T'Size use...;").  13.1(14) seems to
-imply that S'Size = T'Size, whereas 13.3(55) seems to imply that S'Size
-is the minimum needed, based on the range.  Which is correct?  (The
-former.)
-
 !recommendation
 
-(See summary.)
-
 !wording
 
-To Be Determined.
-
 !discussion
 
-In the following examples, assume that the word size is 32 bits.
-
-13.2(7-9) says:
-
-7   The recommended level of support for pragma Pack is:
-
-    8  For a packed record type, the components should be packed as
-       tightly as possible subject to the Sizes of the component
-       subtypes, and subject to any record_representation_clause that
-       applies to the type; the implementation may, but need not,
-       reorder components or cross aligned word boundaries to improve
-       the packing.  A component whose Size is greater than the word
-       size may be allocated an integral number of words.
-
-    9  For a packed array type, if the component subtype's Size is less
-       than or equal to the word size, and Component_Size is not
-       specified for the type, Component_Size should be less than or
-       equal to the Size of the component subtype, rounded up to the
-       nearest factor of the word size.
-
-Consider:
-
-    type Three_Bits is
-        record
-            A, B, C: Boolean;
-        end record;
-    pragma Pack(Three_Bits);
-    type Sixty_Two_Bits is array(1..62) of Boolean;
-    pragma Pack(Sixty_Two_Bits);
-
-Boolean'Size is 1, so clearly Three_Bits can fit in 3 bits, so
-Three_Bits'Size must be 3.  Sixty_Two_Bits can fit in 62 bits,
-so Sixty_Two_Bits'Size must be 62, 63, or 64.
-
-13.9(16-17) says:
-
-16   The recommended level of support for unchecked conversions is:
-
-   17  Unchecked conversions should be supported and should be
-       reversible in the cases where this clause defines the result.  To
-       enable meaningful use of unchecked conversion, a contiguous
-       representation should be used for elementary subtypes, for
-       statically constrained array subtypes whose component subtype is
-       one of the subtypes described in this paragraph, and for record
-       subtypes without discriminants whose component subtypes are
-       described in this paragraph.
-
-This implies that the following Size clauses are legal:
-
-    type Three_Bits is
-        record
-            A, B, C: Boolean;
-        end record;
-    pragma Pack(Three_Bits);
-    for Three_Bits'Size use 3;
-    type Sixty_Two_Bits is array(1..62) of Boolean;
-    pragma Pack(Sixty_Two_Bits);
-    for Sixty_Two_Bits'Size use 64;
-      -- This is either the Size the implementation would choose by
-      -- default, or that value rounded up to a multiple of the word
-      -- size.
-
-Now, consider the case without pragma Pack:
-
-    type Three_Bytes is
-        record
-            A, B, C: Boolean;
-        end record;
-    type Sixty_Two_Bytes is array(1..62) of Boolean;
-
-And assume that the implementation allocates 8 bits for each Boolean
-component, so Three_Bytes'Size = 3*8 and Sixty_Two_Bytes'Size = 62*8, by
-default.  This is not required, but is allowed.  If the implementation
-chooses those values by default, then it must support this as well:
-
-    type Three_Bytes is
-        record
-            A, B, C: Boolean;
-        end record;
-    for Three_Bytes'Size use 3*8;
-    type Sixty_Two_Bytes is array(1..62) of Boolean;
-    for Sixty_Two_Bytes'Size use 62*8;
-        -- Note that this is a multiple of the word size.
-
-A different implementation might allocate 32 bits for each Boolean
-component, and would have to support the corresponding Size clauses.
-
-13.1(23) supports the idea that at least *some* Size clauses ought to be
-required for composite types:
-
-   23  An implementation need not support a specification for the Size
-       for a given composite subtype, nor the size or storage place for
-       an object (including a component) of a given composite subtype,
-       unless the constraints on the subtype and its composite
-       subcomponents (if any) are all static constraints.
-
-13.1(15) says:
-
-  15   A derived type inherits each type-related aspect of its parent type that
-  was directly specified before the declaration of the derived type, or (in the
-  case where the parent is derived) that was inherited by the parent type from
-  the grandparent type.  A derived subtype inherits each subtype-specific
-  aspect of its parent subtype that was directly specified before the
-  declaration of the derived type, or (in the case where the parent is derived)
-  that was inherited by the parent subtype from the grandparent subtype, but
-  only if the parent subtype statically matches the first subtype of the parent
-  type.  An inherited aspect of representation is overridden by a subsequent
-  representation item that specifies the same aspect of the type or subtype.
-
-To resolve the contradiction between 13.1(14) and 13.3(55), we add the
-rule:
-
-  A non-first subtype inherits each subtype-related aspect (namely, Size
-  and Alignment) from the first subtype, if the two subtype are statically
-  matching.
-
-This preserves 13.1(14), which says:
-
-  14   If two subtypes statically match, then their subtype-specific aspects
-  (Size and Alignment) are the same.
-
-13.3(54-55) says:
-
-  54   The recommended level of support for the Size attribute of subtypes is:
-
-     55  The Size (if not specified) of a static discrete or fixed point
-         subtype should be the number of bits needed to represent each
-         value belonging to the subtype using an unbiased representation,
-         leaving space for a sign bit only if the subtype contains
-         negative values.  If such a subtype is a first subtype, then an
-         implementation should support a specified Size for it that
-         reflects this representation.
-
-Now, consider:
-
-    type T is range 1..10;
-    for T'Size use 16; -- T'Size is 16.
-    subtype S1 is T range 1..10; -- S1'Size is 16.
-    subtype S2 is T range 1..5; -- S2'Size is 3.
-
-The first sentence of 13.3(55) does not apply to T, since its Size is
-specified, so its Size is as specified -- 16.  According to this AI,
-the Size of S1 is also specified, since S1 statically matches T, and
-therefore inherits the Size of T.  For S2, however, the Size is not
-specified, so 13.3(55) applies, so S2'Size is 3.
-
-Note that for an integer type T, T'Base and T are never statically
-matching.  For example:
-
-    type T is range -2**31..2**31-1;
-    for T'Size use 32;
-
-If the implementation happens to choose a base range for T'Base that is
-the same as the range of T, that does *not* mean that T'Base statically
-matches T, because T'Base is unconstrained, whereas T is constrained.
-Therefore, we do not specify that T'Base is 32 here.  The base range is
-not a constraint.
-
-The RM defines the recommended level of support as follows:
-
-13.3 says:
-
-29   The recommended level of support for the Alignment attribute for
-subtypes is:
-
-   30  An implementation should support specified Alignments that are
-       factors and multiples of the number of storage elements per word,
-       subject to the following:
-
-   31  An implementation need not support specified Alignments for
-       combinations of Sizes and Alignments that cannot be easily loaded
-       and stored by available machine instructions.
-
-   32  An implementation need not support specified Alignments that are
-       greater than the maximum Alignment the implementation ever
-       returns by default.
-
-These recommendations are hard requirements for implementations that
-support the Systems Programming Annex, by C.2(2):
-
- 2
- The implementation shall support at least the functionality defined by the
- recommended levels of support in Section 13.
-
-These requirements are both vague, and possibly require implementations to
-support non-natural alignments. Therefore, we replace paragraph 31 by specific
-advice.
-
-It seems unreasonable to require arbitrary values (even within the restricted
-set defined above) for discrete types. Values already supported for the class
-make sense, since the implementation already knows how to do such alignments.
-But other alignments could have implementation problems, and don't add any
-real functionality. There may be hardware requirements on the alignment of
-fixed point, floating point, and access types, so we place no requirements
-other than to support "confirming" Alignment clauses. There is no compelling
-reason to require any alignments on task and protected types, so we place
-no requirements on them. For arrays, any alignment supported for the component
-subtype should be supported for the entire array, but no more. For records,
-Tucker thinks some reasonable implementations require alignments and sizes
-to be related, so we adopt a rule to make those implementations possible.
-(Many of us would like more justification for this rule, but Alignments of
-subtypes aren't important enough to worry about it).
-
 !appendix
 
-!section 13.3(55)
-!subject Missing AI: When is the Size "specified" for a subtype?
-!reference RM95-13.3(55)
-!from Tucker Taft 95-10-30
-!reference 95-5373.b Tucker Taft 95-10-30>>
-!discussion
-
-In 13.3(55), it defines a recommended meaning for Size, when it is
-not "specified" for a subtype.  Throughout the language, two
-statically matching subtypes are considered completely equivalent. Hence,
-if a subtype statically matches the first subtype, and the size
-has been specified for the first subtype, then Size should be
-considered "specified" for the statically matching subtype.
-Or to put it another way, all statically matching subtypes should
-have the same value for 'Size.
-
-Any other interpretation of the phrase "if not specified" in
-13.3(55) would create numerous problems.  In particular, if
-one said that specifying a size for a first subtype "broke"
-static matching between the first subtype and other subtypes whose
-constraints statically match those of the first subtype, then putting
-on a "confirming" rep-clause could seriously alter the correctness
-of a program.  Alternatively, if one said that only specifying a
-non-confirming rep-clause would "break" static matching, then compilers
-that differed over what was the default Size for a subtype could have
-dramatically different effects with respect to static subtype matching.
-(Remember that compilers that do not support the S.P. Annex need
-not obey 13.3(55).)
-
-Note that the "Recommended Level of Support" part of the summary becomes
-mandatory in the Systems Programming Annex, whereas the "Implementation
-Advice" does not.
-
-ASIDE:
-
-    Note that there has been some interest in reviving the ability
-    to specify sizes on "secondary" subtypes.  The above suggested
-    interpretation for "specified" should not be interpreted to
-    affect this possibility either way.  If a secondary subtype
-    were to have a Size specified, then we would have to determine
-    how such rep-clauses would interact with static matching.
-    However, even if such rep-clauses were allowed, we believe that
-    when they are *not* present, any subtypes which statically
-    match the first subtype must have the same 'Size as the first
-    subtype.
-
-END OF ASIDE.
-
-****************************************************************
-
-!section 13.1(14)
-!subject Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!from Gary Dismukes 95-11-01
-!reference 95-5379.a Gary Dismukes 95-11-2>>
-!discussion
-
-(This comment is being submitted on behalf of Robert Dewar.)
-
-Some comments on the SIZE problem and Issue
--------------------------------------------
-
-First of all, let's look at the current rules in the absence of size
-clauses:
-
-   type Count is Integer range 1 .. 65;
-
-   subtype Number_Of_Companies is Count range 1 .. 64;
-   subtype Number_Of_Hotels    is Count range 1 .. 65;
-
-   type Count_Ptr     is access all Count;
-   type Companies_Ptr is access all Number_Of_Companies;
-   type Hotels_Ptr    is access all Number_Of_Hotels
-
-We have, according to paragraph 13.3(55):
-
-   Count'Size = 7
-   Number_Of_Companies'Size = 6;
-   Number_Of_Hotels'Size = 7;
-
-This is required. In Ada 83, many (most? nearly all?) compilers would
-have given Integer'Size to all three types, but Ada 95 requires that
-the sizes be minimal. This causes a number of subtle incompatibilities
-but we already (unwisely in my view, I will not hide this) decided to
-introduce this behavior.
-
-Moreover, type Count_Ptr is convertible to type Hotels_Ptr, but
-not to type Companies_Ptr.
-
-This again seems very strange, but that's the way the language is,
-and for this to work, we need to worry about:
-
-   X : aliased Count_Ptr;
-   Y : aliased Hotels_Ptr;
-
-where X'Access and Y'Access must be interconvertible. This means that
-X and Y must be stored using the same representation.
-
-In the absence of Size clauses, Ada 95 achieves this requirement by
-the default size rules in 13.3(55), and in this case 13.1(14) clearly
-is correct:
-
-  "If two subtypes statically match, then their subtype-specific
-   aspects (Size and Alignment) are the same"
-
-Together with the assumption (perhaps it is a requirement, but I
-can't see the reference right now and anyway it is not really
-relevant to this argument which it is) that the two objects will
-be stored the same way if the sizes are the same.
-
-What Happens When we Add Size Clauses
--------------------------------------
-
-13.3(55) allows a size to be specified for the first subtype. If this
-is a confirming size, then all is well, but consider in the above
-example what happens when we write:
-
-   type Count is Integer range 1 .. 65;
-
-   subtype Number_Of_Companies is Count range 1 .. 64;
-   subtype Number_Of_Hotels    is Count range 1 .. 65;
-
-   for Count'Size use 16;
-
-   type Count_Ptr     is access all Count;
-   type Companies_Ptr is access all Number_Of_Companies;
-   type Hotels_Ptr    is access all Number_Of_Hotels
-
-A straightforward reading of 13.3(55) would clearly suggest that the
-size clause affects only the size of Count, and that we would have:
-
-   Count'Size = 16;
-   Number_Of_Companies'Size = 6;
-   Number_Of_Hotels'Size = 7;
-
-But now we are in trouble, the subtypes Count and Number_Of_Hotels
-still appear to staticaly match, but 13.1(14) is violated. So
-something is wrong.
-
-There are two basic approaches one can take to solving this problem:
-
-  Tuck's Approach
-
-    Hereinafter referred to as TA
-
-    TA reads 13.1(14) as a requirement rather than an observation,
-    even though it does not have a shall in it. So the effect of 13.1(14)
-    in TA is that if the other rules on static subtypes are met, then
-    the Size and Alignment SHALL be the same.
-
-    TA reads into the last sentence of 13.3(55) the fact that if you
-    specify the size for the first named subtype, then you also are
-    implicitly specifying the size for any statically matching
-    subtypes (because of the requirement of 13.1(14), and that
-    therefore the default ("if not specified") size rule does not
-    apply.
-
-    Using TA, in the above example, with the size clause, the
-    value of Number_Of_Hotels'Size would become 16.
-
-  Dewar's approach
-
-    Hereinafter referred to as DA
-
-    Does not treat 13.1(14) as a requirement, but rather a statement
-    about what is true about static subtypes. In other words, if this
-    is not true, then the subtypes do not statically match. Roughly
-    the view is that if you state a rule such as:
-
-      "Identical twins always have the same sex"
-
-    and then you look at a boy and a girl, you know they are not identical
-    twins, no matter what rules have been stated elsewhere.
-
-    DA then takes the more natural reading of 13.3(55), and assumes that
-    the size clause applies only to the first named subtype.
-
-  Tuck mentions a third approach as a strawman in his comments on this
-  subject, but (a) I don't understand it, and (b) as far as I can tell
-  no one is arguing for it, so I won't bother with it.
-
-Now, some comments on the two approaches:
-
-1. Both TA and DA allow confirming rep clauses to be added for the first
-   subtype without modifying the behavior in any way. This is important,
-   since apparently one of Tuck's main concerns is that confirming rep
-   clauses not have any semantic effect.
-
-   (I agree that confirming rep clauses should not have any effect, but in
-   the case of Size, this principle is so badly compromised by the inability
-   to give any rep clauses for subtypes at all, not even confirming rep
-   clauses, that I can't get too excited about it, but in any case, DA
-   allows confirming rep clauses that are neutral).
-
-2. DA means that a non-confirming size clause can affect the convertability
-   of pointers to different subtypes. This is presumably the overwhelming
-   concern that leads to the preference of TA.
-
-   However, I must say I am underwhelmed. First of all it is a bit bizarre
-   that the legality of these conversions depends on the equality of values
-   that are likely to be logically related in the program (for example in
-   the above case, if you open a new company, you suddenly get added
-   convertability from Count_Ptr to Companies_Ptr. That's unlikely of
-   course to cause trouble in an existing program. If you remove a hotel,
-   then you lose convertability. This could cause trouble, but in fact is
-   very unlikely to do so, since the conversion from Count_Ptr to
-   Hotels_Ptr is a bizarre one (and the conversion from Hotels_Ptr to
-   Companies_Ptr, which is now allowed is even more bizarre).
-
-   Furthermore, it seems quite natural to me that if you have two types:
-
-      access X
-      access Y
-
-   that they are convertible only if the representations of X and Y are
-   the same, and if you specifically modify the representation of X and
-   do not modify the representation of Y, then they are no longer
-   convertible.
-
-3. TA means that a size clause affects the size of a previously declared
-   subtype. This seems peculiar, and I can see it causing implementation
-   problems. For non subtype specific attributes, there is no problem,
-   since the representation is an attribute of the base type.
-
-   DA does not at all like this retrospective effect.
-
-   TA does not care much, since one pass semantics aren't considered too
-   important, and anyway that's not quite fair, because you can think of
-   sizes as only being established at the freeze point.
-
-4. DA thinks that it is strange that if you specify the size of the first
-   subtype, then it has an effect on a certain subset of subtypes, those
-   which happen to statically match, and that saying that this is the case
-   will complicate 13.3(55). For example, TA could be made clear by adding
-   to this paragraph the following sentence:
-
-     Such a specification affects the first named subtype, and any other
-     subtypes of the same base type that statically match.
-
-   Probably a note needs to be added:
-
-     This affects both subtypes declared previously to the size clause,
-     and any subsequent subtypes declared in either the same declarative
-     region or elsewhere.
-
-   because this is quite surprising (that the size of a subtype in another
-   unit would be affected). The actual processing for subtypes in other
-   units is now something like:
-
-     If the subtype statically matches the first named subtype, then take
-     the size of the first named subtype, otherwise take the default size
-     from paragraph 13.3(55).
-
-   By contrast, the effect of DA on the RM would be as follows:
-
-     Remove 13.1(14) completely
-
-     Add to the first sentence of 4.9.1(2), giving
-
-     "A subtype statically matches another subtype of the same type if they
-      have statically matching constraints, and if they have the same
-      subtype specific aspects (Size and Alignment)".
-
-What we have here is two conflicting requirements in the RM. I think in such
-cases it is a waste of time to make arguments saying essentially that you
-can conclude that one is wrong by intent because it must be wrong, given
-the other requirement. This argument can be applied either way round and
-is unhelpful. I mention this, because TA uses this argument, arguing that
-13.1(14) implies the desired constructive reading of 13.3(55). DA could
-make the same argument the other way round, but it is besides the point.
-
-What we need is a resolution that is least suprising, and simplest.
-
-Ulterior Motive Disclosed
--------------------------
-
-DA will now disclose an ulterior motive.
-
-Up until the last moment, Ada 95 allowed 'Size to be specified for subtypes.
-GNAT implemented this capability, and it was definitely useful. It was
-removed from the RM late on without WG9 discussion.
-
-Why?
-
-Because of these static matching rules. The attempt was to ensure that
-13.1(14) is in fact true, and that specifying sizes for subtypes could
-not disrupt it.
-
-But that did not get done cleanly as we see.
-
-To me, the removal of a really useful feature, just so that the very
-marginal feature of being able to convert pointers to logically unrelated
-subtypes would work, is a very poor trade off.
-
-It is particularly important to be able to specify the size of subtypes
-given the (in my view injudicious) introduction of the rules in Ada 95
-that require separate sizes for subtypes (Ada 83 allowed it but did not
-require it, few compilers took advantage of it, the only one I know of
-that did systematically what is now required is the old Intermetrics
-compiler).
-
-This means that if we have
-
-   type X is range 0 .. 65535;
-   for X'Size use 16;
-
-   subtype Y is X range 1 .. N;
-   -- N is a constant that happens today to be 255
-
-   then Y'Size is 8, and that in the record:
-
-      type Rec is record
-         XV : X;
-         YV : Y;
-      end record;
-
-   XV is likely to occupy 16 bits, and YV to occupy 8 bits. This could well
-   be incompatible with existing programs, and note that it would require
-   most vendors to change their size rules, and behavior of their systems
-   (with the sole exception of the Intermetrics compiler, which is indeed
-   compatible with the old Intermetrics compiler).
-
-This was not *too* worrisome before the last minute change, since at least
-you could use a size clause (in this case "for Y'size use X'Size) that
-would override the default, and duplicate old behavior.
-
-Furthermore, the introduction of the restriction means that it is not
-possible to specify confirming size clauses. So you have a situation in
-which compared to Ada 83, the sizes of subtypes are required to vary in
-an unexpected manner, and there is no way to either confirm or change
-this behavior.
-
-DA has the very interesting property that if it is adopted, then there is
-no reason not to allow compilers to specify the size of subtypes, undoing
-the ill effects of the last minute, incompletely executed, change.
-
-A comment here is that MANY readers of Ada 95 assume that subtype specific
-attributes can be specified for subtypes. That seems a reasonable assumption
-and used to be a correct one, but is now surprisingly false. We have got a
-number of bug reports from people complaining that GNAT does not allow such
-specifications. We can of course explain that GNAT is right, but the
-principle of least suprise is definitely violated!
-
-Incidentally, a major use for specifying subtype sizes is in building
-packed records. You just specify the size of each subtype, and then say
-pragma Pack, and everything packs together nicely without needing to
-write a (possibly non-portable) representation clause. Furthermore
-the representation clause here is clearly undesirable over-specification.
-You don't want to specify the exact layout, but you do want to control
-the nature of the packing. Yes there are other ways to do this, e.g.
-by using derived types, but they are messy by comparison.
-
-The other major reason for specifying subtype sizes is in porting legacy
-code, where you want to confirm size choices made by a previous Ada 83
-compiler.
-
-These requirements are strong enough that in GNAT we definitely intend to
-implement a feature for this purpose.
-
-If TA is adopted, GNAT will introduce an attribute Subtype_Size that can
-be applied to arbitrary subtypes, and which will compromise static matching
-in some cases. This attribute is probably technically an extension because
-of this compromising effect, so we will put it under the non-pedantic (GNU'ese
-for extensions allowed) mode.
-
-If DA is adopted, GNAT will simply allow 'Size for subtypes.
-
-A note for Bob Duff
--------------------
-
-Yes, yes, all this applies to Alignment too. I can't get excited about
-alignments for subtypes. At least there is no analog to 13.3(55) requiring
-an injudicious choice of default alignments.
-
-To be Honest
-------------
-
-There are a couple more glitches here
-
-First, with respect to dynamic subtypes. We have to worry about dynamic
-subtypes, since they can statically match. For dynamic subtypes, if you
-want to be sure that access types to them are inter-convertible, then
-you have to read 13.1(14) as a requirement that the sizes of statically
-matching dynamic subtypes match. Note that there are no rules on the
-default sizes for dynamic subtypes. TA of course handles this fine, by
-changing the "are" in 13.1(14) to "shall".
-
-DA can't get very excited about this problem, and doesn't really care
-if convertability of such access types is impl dependent, but, if pressed,
-would be inclined to require that all dynamic subtypes have the size
-of the base type. This avoids differences between implementations, and
-is perfectly acceptable in practice.
-
-Second, with respect to alignments, there is no clear statement that requires
-choice of alignments. TA would say that 13.1(14) places the requirement that
-if two subtypes statically match then the alignments should match. Again
-DA can't get excited, but if pressed would be inclined to say that the
-alignments of two subtypes of the same size should be identical.
-
-Original Intent
----------------
-
-Arguments from original intent are somewhat bogus, since the RM does not
-contain its history.
-
-One could say that the longer term intent was that Size should be able
-to be specified for subtypes, and that the language "subtype specific"
-still implies this -- a bogus argument for DA.
-
-One could also say that the removal of this capability obviously means
-that 13.1(14) was considered sacrosanct -- a bogus argument for TA.
-
-Conclusion
-----------
-
-There is a real disagreement here. Needs discussion!
-
-
-
-****************************************************************
-
-!section 13.1(14)
-!subject 'SIZE problem violates Ada95 "no surprises" issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 95-5379.a Gary Dismukes 95-11-2
-!from David Emery 95-11-02
-!reference 95-5382.a David_Emery_at_1-BCCDFA@CCGATE.HAC.COM 95-11-3>>
-!discussion
-
-RBKD's example:
-
-   type X is range 0 .. 65535;
-   for X'Size use 16;
-
-   subtype Y is X range 1 .. N;
-   -- N is a constant that happens today to be 255
-
-   then Y'Size is 8, and that in the record:
-
-      type Rec is record
-         XV : X;
-         YV : Y;
-      end record;
-led me to observe that the following:
-    package Rec_IO is new Direct_IO (Rec);
-would cause real problems when a database is maintained using
-Rec_IO bt different invocations of the program, with different
-values of N.    The expectation (guaranteed by Ada83 because Y
-is a subtype and not a type, I beleive), is that objects of
-type Rec are the same size.  This is a particular issue for
-Direct_IO, where the data layouts can depend very strongly on
-the size of the object.
-
-Ada95 clearly violates its "no surprises" guideline by having
-the size of a subtype change in this way.  I find it basically
-counterintuitive (and unacceptable) to have to do a lot of
-representation clauses for an 'invariant' that should be machine
-independent, i.e. that objects of the type Rec are the same
-size, regardless of the value of the constraint N.  In particular,
-if this causes Direct_IO to fail because of varying values of N,
-then we lose type 'equivalence', exchanging it for subtype
-equivalence.  (What I mean here is that 2 values of the same type
-can be used, subject only to subtype constraint checks.)
-
-                dave
-
-
-****************************************************************
-
-!section 13.1(14)
-!subject Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 95-5379.a Gary Dismukes 95-11-2
-!from Bob Duff
-!reference 96-5462.a Robert A Duff 96-4-11>>
-!discussion
-
-Robert, you sent in this comment just before the last ARG meeting.
-It was discussed at the meeting, with no resolution of the issues.
-There are some confusing things.  Could you please send a
-clarification?
-
-> (This comment is being submitted on behalf of Robert Dewar.)
->
-> Some comments on the SIZE problem and Issue
-> -------------------------------------------
->
-> First of all, let's look at the current rules in the absence of size
-> clauses:
->
->    type Count is Integer range 1 .. 65;
-
-That's not legal syntax.  You must mean one of these:
-
-    type Count is range 1 .. 65;
-    subtype Count is Integer range 1 .. 65;
-    type Count is new Integer range 1 .. 65;
-
-The ARG discussion got confused about this.
-
->    subtype Number_Of_Companies is Count range 1 .. 64;
->    subtype Number_Of_Hotels    is Count range 1 .. 65;
-
-There was some feeling at the ARG meeting that this is not a compelling
-example, because you're using the same type (two different subtypes) for
-two totally unrelated things.  If this causes surprises, tough luck --
-you should have used two different types in the first place.
-
-Now, I realize there are (at least) two schools of thought -- some
-people like to use lots of different types, whereas some people like to
-make everything a subtype of the same type.  Anyway, you weren't there
-to defend yourself, so you might want to do so now.
-
->    type Count_Ptr     is access all Count;
->    type Companies_Ptr is access all Number_Of_Companies;
->    type Hotels_Ptr    is access all Number_Of_Hotels
->
-> We have, according to paragraph 13.3(55):
->
->    Count'Size = 7
->    Number_Of_Companies'Size = 6;
->    Number_Of_Hotels'Size = 7;
->
-> This is required. In Ada 83, many (most? nearly all?) compilers would
-> have given Integer'Size to all three types, but Ada 95 requires that
-> the sizes be minimal. This causes a number of subtle incompatibilities
-> but we already (unwisely in my view, I will not hide this) decided to
-> introduce this behavior.
->
-> Moreover, type Count_Ptr is convertible to type Hotels_Ptr, but
-> not to type Companies_Ptr.
->
-> This again seems very strange, but that's the way the language is,
-> and for this to work, we need to worry about:
->
->    X : aliased Count_Ptr;
->    Y : aliased Hotels_Ptr;
->
-> where X'Access and Y'Access must be interconvertible. This means that
-> X and Y must be stored using the same representation.
->
-> In the absence of Size clauses, Ada 95 achieves this requirement by
-> the default size rules in 13.3(55), and in this case 13.1(14) clearly
-> is correct:
->
->   "If two subtypes statically match, then their subtype-specific
->    aspects (Size and Alignment) are the same"
->
-> Together with the assumption (perhaps it is a requirement, but I
-> can't see the reference right now and anyway it is not really
-> relevant to this argument which it is) that the two objects will
-> be stored the same way if the sizes are the same.
-
-I don't think there's an explicit requirement, but it seems that this is
-the only viable run-time model -- aliased objects have to be stored the
-same way if their type is the same, and their subtypes statically match.
-The compiler can play all kinds of games with non-aliased objects.
-
-> What Happens When we Add Size Clauses
-> -------------------------------------
->
-> 13.3(55) allows a size to be specified for the first subtype. If this
-> is a confirming size, then all is well, but consider in the above
-> example what happens when we write:
->
->    type Count is Integer range 1 .. 65;
-
-Same bug as above.
-
->    subtype Number_Of_Companies is Count range 1 .. 64;
->    subtype Number_Of_Hotels    is Count range 1 .. 65;
->
->    for Count'Size use 16;
->
->    type Count_Ptr     is access all Count;
->    type Companies_Ptr is access all Number_Of_Companies;
->    type Hotels_Ptr    is access all Number_Of_Hotels
->
-> A straightforward reading of 13.3(55) would clearly suggest that the
-> size clause affects only the size of Count, and that we would have:
->
->    Count'Size = 16;
->    Number_Of_Companies'Size = 6;
->    Number_Of_Hotels'Size = 7;
->
-> But now we are in trouble, the subtypes Count and Number_Of_Hotels
-> still appear to staticaly match, but 13.1(14) is violated. So
-> something is wrong.
->
-> There are two basic approaches one can take to solving this problem:
->
->   Tuck's Approach
->
->     Hereinafter referred to as TA
->
->     TA reads 13.1(14) as a requirement rather than an observation,
->     even though it does not have a shall in it. So the effect of 13.1(14)
->     in TA is that if the other rules on static subtypes are met, then
->     the Size and Alignment SHALL be the same.
-
-There are lots of requirements that have no "shall".  Legality Rules use
-"shall", but Static Semantics just state "facts" about the language --
-in this case, the sizes "are" the same.  The facts are of course
-requirements on the implementation -- if they're not true in a given
-implementation, then that's not a correct implementation of Ada.
-My point is: Don't base your argument on whether "shall" was used.
-
-I do admit we have a problem, here.
-
->     TA reads into the last sentence of 13.3(55) the fact that if you
->     specify the size for the first named subtype, then you also are
->     implicitly specifying the size for any statically matching
->     subtypes (because of the requirement of 13.1(14), and that
->     therefore the default ("if not specified") size rule does not
->     apply.
->
->     Using TA, in the above example, with the size clause, the
->     value of Number_Of_Hotels'Size would become 16.
->
->   Dewar's approach
->
->     Hereinafter referred to as DA
->
->     Does not treat 13.1(14) as a requirement, but rather a statement
->     about what is true about static subtypes. In other words, if this
->     is not true, then the subtypes do not statically match. Roughly
->     the view is that if you state a rule such as:
->
->       "Identical twins always have the same sex"
->
->     and then you look at a boy and a girl, you know they are not identical
->     twins, no matter what rules have been stated elsewhere.
-
-No, that's not right.  If the RM said that, we would have written "An
-identical twins is a pair of siblings that have the same sex [...and a
-bunch of other stuff]".  Or, "NOTE: Note that identical twins always
-have the same sex." (presuming it follows from the definition).
-
-I wrote 13.1(14), and it's written in the same style as all the other
-Static Semantics, and it means that we are *requiring* this to be true
-in all implementations.
-
->     DA then takes the more natural reading of 13.3(55), and assumes that
->     the size clause applies only to the first named subtype.
->
->   Tuck mentions a third approach as a strawman in his comments on this
->   subject, but (a) I don't understand it, and (b) as far as I can tell
->   no one is arguing for it, so I won't bother with it.
->
-> Now, some comments on the two approaches:
->
-> 1. Both TA and DA allow confirming rep clauses to be added for the first
->    subtype without modifying the behavior in any way. This is important,
->    since apparently one of Tuck's main concerns is that confirming rep
->    clauses not have any semantic effect.
->
->    (I agree that confirming rep clauses should not have any effect, but in
->    the case of Size, this principle is so badly compromised by the inability
->    to give any rep clauses for subtypes at all, not even confirming rep
->    clauses, that I can't get too excited about it, but in any case, DA
->    allows confirming rep clauses that are neutral).
->
-> 2. DA means that a non-confirming size clause can affect the convertability
->    of pointers to different subtypes. This is presumably the overwhelming
->    concern that leads to the preference of TA.
->
->    However, I must say I am underwhelmed. First of all it is a bit bizarre
->    that the legality of these conversions depends on the equality of values
->    that are likely to be logically related in the program (for example in
->    the above case, if you open a new company, you suddenly get added
->    convertability from Count_Ptr to Companies_Ptr. That's unlikely of
->    course to cause trouble in an existing program. If you remove a hotel,
->    then you lose convertability. This could cause trouble, but in fact is
->    very unlikely to do so, since the conversion from Count_Ptr to
->    Hotels_Ptr is a bizarre one (and the conversion from Hotels_Ptr to
->    Companies_Ptr, which is now allowed is even more bizarre).
-
-This is where the two schools of thought I mentioned make a difference
--- u would make Number_Of_Hotels and
-Number_Of_Companies two different types, so convertibility changes would
-not happen.
-
->    Furthermore, it seems quite natural to me that if you have two types:
->
->       access X
->       access Y
->
->    that they are convertible only if the representations of X and Y are
->    the same, and if you specifically modify the representation of X and
->    do not modify the representation of Y, then they are no longer
->    convertible.
->
-> 3. TA means that a size clause affects the size of a previously declared
->    subtype. This seems peculiar, and I can see it causing implementation
->    problems. For non subtype specific attributes, there is no problem,
->    since the representation is an attribute of the base type.
->
->    DA does not at all like this retrospective effect.
->
->    TA does not care much, since one pass semantics aren't considered too
->    important, and anyway that's not quite fair, because you can think of
->    sizes as only being established at the freeze point.
-
-Note that this "retrospective" effect happens only within a single
-package spec or declarative part.
-
-Now wait a minute, is this really right?  Don't freezing rules require
-you to give the size clause before any other *constrained* subtypes?
-
-> 4. DA thinks that it is strange that if you specify the size of the first
->    subtype, then it has an effect on a certain subset of subtypes, those
->    which happen to statically match, and that saying that this is the case
->    will complicate 13.3(55). For example, TA could be made clear by adding
->    to this paragraph the following sentence:
->
->      Such a specification affects the first named subtype, and any other
->      subtypes of the same base type that statically match.
->
->    Probably a note needs to be added:
->
->      This affects both subtypes declared previously to the size clause,
->      and any subsequent subtypes declared in either the same declarative
->      region or elsewhere.
->
->    because this is quite surprising (that the size of a subtype in another
->    unit would be affected). The actual processing for subtypes in other
->    units is now something like:
->
->      If the subtype statically matches the first named subtype, then take
->      the size of the first named subtype, otherwise take the default size
->      from paragraph 13.3(55).
->
->    By contrast, the effect of DA on the RM would be as follows:
->
->      Remove 13.1(14) completely
->
->      Add to the first sentence of 4.9.1(2), giving
->
->      "A subtype statically matches another subtype of the same type if they
->       have statically matching constraints, and if they have the same
->       subtype specific aspects (Size and Alignment)".
->
-> What we have here is two conflicting requirements in the RM. I think in such
-> cases it is a waste of time to make arguments saying essentially that you
-> can conclude that one is wrong by intent because it must be wrong, given
-> the other requirement. This argument can be applied either way round and
-> is unhelpful. I mention this, because TA uses this argument, arguing that
-> 13.1(14) implies the desired constructive reading of 13.3(55). DA could
-> make the same argument the other way round, but it is besides the point.
->
-> What we need is a resolution that is least suprising, and simplest.
->
-> Ulterior Motive Disclosed
-> -------------------------
->
-> DA will now disclose an ulterior motive.
->
-> Up until the last moment, Ada 95 allowed 'Size to be specified for subtypes.
-> GNAT implemented this capability, and it was definitely useful. It was
-> removed from the RM late on without WG9 discussion.
->
-> Why?
->
-> Because of these static matching rules. The attempt was to ensure that
-> 13.1(14) is in fact true, and that specifying sizes for subtypes could
-> not disrupt it.
->
-> But that did not get done cleanly as we see.
-
-This history is correct.
-
-> To me, the removal of a really useful feature, just so that the very
-> marginal feature of being able to convert pointers to logically unrelated
-> subtypes would work, is a very poor trade off.
->
-> It is particularly important to be able to specify the size of subtypes
-> given the (in my view injudicious) introduction of the rules in Ada 95
-> that require separate sizes for subtypes (Ada 83 allowed it but did not
-> require it, few compilers took advantage of it, the only one I know of
-> that did systematically what is now required is the old Intermetrics
-> compiler).
->
-> This means that if we have
->
->    type X is range 0 .. 65535;
->    for X'Size use 16;
->
->    subtype Y is X range 1 .. N;
->    -- N is a constant that happens today to be 255
-
-I presume that N is a *static* constant.  Dave Emery sent a note that
-assumed N is non-static, which I think confuses the issue.
-
->    then Y'Size is 8, and that in the record:
->
->       type Rec is record
->          XV : X;
->          YV : Y;
->       end record;
->
->    XV is likely to occupy 16 bits, and YV to occupy 8 bits. This could well
->    be incompatible with existing programs, and note that it would require
->    most vendors to change their size rules, and behavior of their systems
->    (with the sole exception of the Intermetrics compiler, which is indeed
->    compatible with the old Intermetrics compiler).
->
-> This was not *too* worrisome before the last minute change, since at least
-> you could use a size clause (in this case "for Y'size use X'Size) that
-> would override the default, and duplicate old behavior.
->
-> Furthermore, the introduction of the restriction means that it is not
-> possible to specify confirming size clauses. So you have a situation in
-> which compared to Ada 83, the sizes of subtypes are required to vary in
-> an unexpected manner, and there is no way to either confirm or change
-> this behavior.
-
-However, note that Ada 95 allows Size clauses on *objects* and
-Component_Size clauses for array components, which somewhat alleviates
-the problem.  Also, if you really want a Size clause on a subtype, you
-can make it a derived type instead.  Not ideal, since extra type
-conversion will be needed, but it does work OK.
-
-> DA has the very interesting property that if it is adopted, then there is
-> no reason not to allow compilers to specify the size of subtypes, undoing
-> the ill effects of the last minute, incompletely executed, change.
->
-> A comment here is that MANY readers of Ada 95 assume that subtype specific
-> attributes can be specified for subtypes. That seems a reasonable assumption
-> and used to be a correct one, but is now surprisingly false. We have got a
-> number of bug reports from people complaining that GNAT does not allow such
-> specifications. We can of course explain that GNAT is right, but the
-> principle of least suprise is definitely violated!
->
-> Incidentally, a major use for specifying subtype sizes is in building
-> packed records. You just specify the size of each subtype, and then say
-> pragma Pack, and everything packs together nicely without needing to
-> write a (possibly non-portable) representation clause. Furthermore
-> the representation clause here is clearly undesirable over-specification.
-> You don't want to specify the exact layout, but you do want to control
-> the nature of the packing. Yes there are other ways to do this, e.g.
-> by using derived types, but they are messy by comparison.
->
-> The other major reason for specifying subtype sizes is in porting legacy
-> code, where you want to confirm size choices made by a previous Ada 83
-> compiler.
->
-> These requirements are strong enough that in GNAT we definitely intend to
-> implement a feature for this purpose.
->
-> If TA is adopted, GNAT will introduce an attribute Subtype_Size that can
-> be applied to arbitrary subtypes, and which will compromise static matching
-> in some cases. This attribute is probably technically an extension because
-> of this compromising effect, so we will put it under the non-pedantic (GNU'ese
-> for extensions allowed) mode.
-
-No, I don't think you need to play the "-pedantic" game.
-Implementation-defined attributes can do whatever you like.
-The only barrier is the wisdom and good taste of the compiler
-writer.  ;-)
-
-> If DA is adopted, GNAT will simply allow 'Size for subtypes.
-
-No, *that's* not allowed.  Unless, of course, the ARG explicitly rules
-that it *is* allowed.
-
-> A note for Bob Duff
-> -------------------
->
-> Yes, yes, all this applies to Alignment too. I can't get excited about
-> alignments for subtypes. At least there is no analog to 13.3(55) requiring
-> an injudicious choice of default alignments.
-
-And of course for Alignment there's no issue of compatibility with
-existing Ada 83 compilers.
-
-We can decide what the right thing for Size is, and then simply rule
-that Alignment works the same way, which I think is necessary.
-
-> To be Honest
-> ------------
->
-> There are a couple more glitches here
->
-> First, with respect to dynamic subtypes. We have to worry about dynamic
-> subtypes, since they can statically match. For dynamic subtypes, if you
-> want to be sure that access types to them are inter-convertible, then
-> you have to read 13.1(14) as a requirement that the sizes of statically
-> matching dynamic subtypes match. Note that there are no rules on the
-> default sizes for dynamic subtypes. TA of course handles this fine, by
-> changing the "are" in 13.1(14) to "shall".
-
-No, that's not the correct wording for TA.  As I said before, the Static
-Semantics *never* say "shall", they always say "are", and there's no
-reason for this case to be any different.  But that's a wording issue.
-
-> DA can't get very excited about this problem, and doesn't really care
-> if convertability of such access types is impl dependent, but, if pressed,
-> would be inclined to require that all dynamic subtypes have the size
-> of the base type. This avoids differences between implementations, and
-> is perfectly acceptable in practice.
-
-Well, dynamic subtypes are probably fairly rare.  Nonetheless, I think
-it is desirable to *allow* a compiler to deduce a smaller size than the
-base SUBtype, for dynamic subtypes.
-
-> Second, with respect to alignments, there is no clear statement that requires
-> choice of alignments. TA would say that 13.1(14) places the requirement that
-> if two subtypes statically match then the alignments should match. Again
-> DA can't get excited, but if pressed would be inclined to say that the
-> alignments of two subtypes of the same size should be identical.
-
-I'm not sure what you mean by not getting excited, but clearly, if your
-compiler doesn't obey this, then type conversions of access types simply
-won't work.
-
-> Original Intent
-> ---------------
->
-> Arguments from original intent are somewhat bogus, since the RM does not
-> contain its history.
->
-> One could say that the longer term intent was that Size should be able
-> to be specified for subtypes, and that the language "subtype specific"
-> still implies this -- a bogus argument for DA.
->
-> One could also say that the removal of this capability obviously means
-> that 13.1(14) was considered sacrosanct -- a bogus argument for TA.
-
-I agree that arguments about "intent" are often bogus.  The language
-designer doesn't always have an accurate memory of intent.  Of course,
-in many cases, there is evidence in the AARM about the intent.  In
-*this* case, the intent was self contradictory -- the language designers
-intended to support Size clauses on non-first subtypes, and also
-intended that static matching for static subtypes work as it does, and
-also intended that low-level mucking with rep clauses should not affect
-the high-level pristine semantics of static matching.  Clearly, one
-cannot achieve all of that "intent", so something's got to give.  At the
-last minute, we chose to ditch size clauses on non-first subtypes.
-
-> Conclusion
-> ----------
->
-> There is a real disagreement here. Needs discussion!
-
-Indeed.
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Size attribute
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!from Bob Duff
-!reference 96-5463.a Robert A Duff 96-4-11>>
-!discussion
-
-Here are some general comments on the Size issue.
-
-First of all, in all these discussions, PLEASE make sure it's very clear
-whether you're talking about a query of the Size attribute, or a Size
-clause.  Numerous times, discussions on this issue have become mired in
-confusion, because I said something about the query, when Robert thought
-I was talking about the clause, or vice versa.
-
-Also, please be sure to distinguish the Size of a subtype from the Size
-of an object, and the corresponding clauses from each other.  The
-semantics are rather different -- the Size of a subtypes is rather
-flaky, whereas the Size of an object is pretty well defined.
-
-One principle that most people seem to like is that a "confirming rep
-clause" should not change things.  That is, if you have a program where
-T'Size = 32 by default, and you add a rep clause, "for T'Size use 32;",
-then the semantics of the new program should be identical.
-
-For most rep clauses, in most situations, we have achieved this
-principle.  However, there are some cases where the principle is
-compromised.  In particular 13.3(50-52) says:
-
-  50   If the Size of a subtype is specified, and allows for efficient
-  independent addressability (see 9.10) on the target architecture, then the
-  Size of the following objects of the subtype should equal the Size of the
-  subtype:
-
-     51  Aliased objects (including components).
-
-     52  Unaliased components, unless the Size of the component is
-         determined by a component_clause or Component_Size clause.
-
-The phrase "If the Size of a subtype is specified" clearly violates the
-principle that confirming rep clauses shouldn't change things.  The
-principle is still a good principle -- we probably ought to at least try
-to minimize the cases where it is compromised.
-
-Note well para 51.  The Size of a stand-alone object matters to a
-programmer if the programmer takes the Address of that object, and
-passes that address off to some other language.  The address ought to be
-pointing at a sequence of bytes of the expected size.  The reason para
-51 says "aliased" is that 'Address is only well-defined in the case of
-aliased objects, by 13.3(16):
-
-   16  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.
-
-Thus, if you say:
-
-    X: Integer; -- not aliased
-    ...X'Address ...
-
-the compiler might put X in a register, and return a null address for
-X'Address (or even raise an exception).
-
-In thinking about Size, note that there can be subtypes whose range is
-wider than the first subtype:
-
-    type T is range 0..15; -- T'Size = 4
-    subtype S is T'Base range -15..15; -- S'Size = 5
-
-The above subtype S is guaranteed to be supported on all
-implementations.  My point is that a rule requiring the size of all
-subtypes to be the same as the first subtype just won't work.  For
-example, even if you don't agree that T'Size should be 4 by default, one
-could legally add "for T'Size use 4;" to the above -- certainly that was
-legal in Ada 83, and it had better still be legal.  But that Size clause
-clearly cannot mean T'Base'Size = 4, nor that S'Size = 4.
-
-Robert and I seem to disagree on the desired semantics of packed
-records.  This makes a difference to the Size clause issue, so I think
-the ARG should explicitly consider what is desirable for packed records.
-(I should note that one Ada 83 compiler doesn't support packed records
-at all.  Robert is correct that it would be nice to be compatible with
-that compiler, but if it conflicts with the way packed records have to
-work, it's not suprising to me that this compatibility is impossible to
-achieve).
-
-Here's my view of packed records.  Assume a 32-bit machine with 8-bit
-bytes.
-
-    type My_Boolean is new Boolean; -- My_Boolean'Size = 1.
-    type My_Other_Boolean is (No, Yes); -- My_Other_Boolean'Size = 1.
-    subtype One_Bit_Int is Integer range 0..1; -- One_Bit_Int'Size = 1.
-
-    type Inner_Record is
-        record
-            X: My_Boolean;
-            Y: My_Other_Boolean;
-            Z: One_Bit_Int;
-        end record;
-    pragma Pack(Inner_Record);
-
-    type Twenty_Nine_Bits is range 0..2**29-1; -- Twenty_Nine_Bits'Size = 29.
-
-    type Outer_Record is
-        record
-            Inner: Inner_Record;
-            W: Twenty_Nine_Bits;
-        end record;
-    pragma Pack(Outer_Record);
-
-To me, it seems highly desirable that the Size values shown above should
-be chosen by default, and that Outer_Record should fit in a single
-32-bit word, and that Outer_Record'Size should be 32.
-
-My understanding is that 13.2(8) requires this:
-
-    8  For a packed record type, the components should be packed as
-       tightly as possible subject to the Sizes of the component
-       subtypes, and subject to any record_representation_clause that
-       applies to the type; the implementation may, but need not,
-       reorder components or cross aligned word boundaries to improve
-       the packing.  A component whose Size is greater than the word
-       size may be allocated an integral number of words.
-
-I believe Robert's view (please correct me if I'm wrong) is that the
-programmer should have to write some Size clauses, in order to achieve
-the above tight packing.  For example, the user would have to write:
-
-    for One_Bit_Int'Size use 1;
-    for Twenty_Nine_Bits'Size use 29;
-
-I'm not sure if Robert's view also requires:
-
-    for My_Boolean'Size use 1;
-    for My_Other_Boolean'Size use 1;
-
-in addition.  If so, that's pretty strange, because Boolean'Size = 1
-(even though Boolean has no representation clause in Standard).  If not,
-that's even stranger, since I would expect integers and enumerations to
-behave the same way in this regard.
-
-In any case, I don't see why the user should have to write Size clauses
-to get reasonable packing.  That defeats the purpose of pragma Pack.  I
-don't care to specify all kinds of details -- I just want the compiler
-to choose a reasonably-packed representation.  (If I *did* care about
-details, I would use a record_rep_clause instead.)
-
-Certainly, in the Pascal compilers I've used, packed records are packed
-according to the sub-ranges declared, without any need for Size clauses
-(which is lucky, since Pascal doesn't have Size clauses).
-
-Now, one could imagine that the record is packed like I want it, but the
-'Size values are not as I indicated above.  I don't see how this can
-work.  The very meaning of 'Size is that there are no objects smaller
-than that (barring other overriding rep clauses).  Also, we don't want
-to say that packing is different depending on whether the Size was
-specified or chosen by default.
-
-I think Robert's view is that requiring the Size clauses is desirable,
-because then the desired packing won't silently change if you change the
-bounds of Twenty_Nine_Bits, for example -- you'll either get the same
-package, or you'll get an error message on the Size clause.  Obviously,
-I don't agree that this is desirable.
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Size attribute
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5463.a Robert A Duff 96-4-11
-!from Keith Thompson 96-04-12
-!reference 96-5466.a Keith Thompson 96-4-12>>
-!discussion
-
-Bob Duff writes:
-> One principle that most people seem to like is that a "confirming rep
-> clause" should not change things.  That is, if you have a program where
-> T'Size = 32 by default, and you add a rep clause, "for T'Size use 32;",
-> then the semantics of the new program should be identical.
->
-> For most rep clauses, in most situations, we have achieved this
-> principle.  However, there are some cases where the principle is
-> compromised.  In particular 13.3(50-52) says:
->
->   50   If the Size of a subtype is specified, and allows for efficient
->   independent addressability (see 9.10) on the target architecture, then the
->   Size of the following objects of the subtype should equal the Size of the
->   subtype:
->
->      51  Aliased objects (including components).
->
->      52  Unaliased components, unless the Size of the component is
->          determined by a component_clause or Component_Size clause.
->
-> The phrase "If the Size of a subtype is specified" clearly violates the
-> principle that confirming rep clauses shouldn't change things.  The
-> principle is still a good principle -- we probably ought to at least try
-> to minimize the cases where it is compromised.
-
-In most cases, this doesn't necessarily violate the principle; at
-worst, it's an incomplete statement.  Surely if the Size of a subtype,
-*whether explicitly specified or not*, allows for efficient independent
-addressability, aliased objects and unaliased components should have
-the same Size as the subtype.
-
-For example, if T'Size is 32 by default, aliased objects and unaliased
-components should have a 'Size of 32 whether or not there's a confirming
-size clause "for T'Size use 32".
-
-The only case I can think of where there might be a conflict is for
-a subtype that isn't a first subtype, like this:
-
-    subtype Byte_Integer is Integer range -128 .. 127;
-    -- Integer'Size = (say) 32, Byte_Integer'Size = 8
-    Obj: aliased Byte_Integer;
-    -- Obj'Size = 32?
-
-In this case, it's reasonable for Obj'Size to be 32.  This doesn't
-conflict with 13.3(50-52), but it does conflict with the interpretation
-that it should apply whether or not the size is specified.
-
-I hope I've at least narrowed down the conflicting cases.
-
-****************************************************************
-
-!section 13.1(14)
-!subject Size attribute
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5463.a Robert A Duff 96-4-11
-!from Bob Duff
-!reference 96-5467.a Robert A Duff 96-4-12>>
-!discussion
-
-Keith Thompson says:
-
-> In most cases, this [13.3(50-52)] doesn't necessarily violate the
-> principle; at worst, it's an incomplete statement.
-
-Technically true.  However, consider the 80386.  You can load 8-bit and
-32-bit quantities most efficiently, 16-bit quantities slightly less
-efficiently.  3-bit quantities are out of the question, since they would
-require extra locking code, but 16-bit quantities are efficient enough
-to be called "efficient" -- at least that was *my* intent.
-
-So, if you write:
-
-    type T1 is range 0..2**16-1; -- T1'Size = 16
-    X1: T1; -- X1'Size = 32
-
-    type T2 is range 0..2**16-1; -- T2'Size = 16
-    for T2'Size use 16;
-    X2: T2; -- X2'Size = 16
-
-This is certainly an allowed implementation, and it seems to me a
-desirable implementation.  It violates the principle, since T1'Size and
-T2'Size are both 16, but the meaning of their Size is different, since
-one is "16 by default" and the other is "specified as 16".
-
-Here's another "principle", which I'm not sure anybody else agrees with,
-but it makes sense to me: If you don't give any rep clauses, then the
-compiler ought to do what's most efficient.  If you care about
-representation more than (the compiler's notion of) efficiency, then
-give a rep clause.  "Predictable representations" is not a goal, if
-there are no rep clauses.
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Size attribute
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5463.a Robert A Duff 96-4-11
-!from Bob Duff
-!reference 96-5468.a Robert A Duff 96-4-12>>
-!discussion
-
-Oops.  In the message I just sent, I forgot to put "aliased".  Sorry.
-Here's a correction:
-
-Keith Thompson says:
-
-> In most cases, this [13.3(50-52)] doesn't necessarily violate the
-> principle; at worst, it's an incomplete statement.
-
-Technically true.  However, consider the 80386.  You can load 8-bit and
-32-bit quantities most efficiently, 16-bit quantities slightly less
-efficiently.  3-bit quantities are out of the question, since they would
-require extra locking code, but 16-bit quantities are efficient enough
-to be called "efficient" -- at least that was *my* intent.
-
-So, if you write:
-
-    type T1 is range 0..2**16-1; -- T1'Size = 16
-    X1: aliased T1; -- X1'Size = 32
-
-    type T2 is range 0..2**16-1; -- T2'Size = 16
-    for T2'Size use 16;
-    X2: aliased T2; -- X2'Size = 16
-
-This is certainly an allowed implementation, and it seems to me a
-desirable implementation.  It violates the principle, since T1'Size and
-T2'Size are both 16, but the meaning of their Size is different, since
-one is "16 by default" and the other is "specified as 16".
-
-Here's another "principle", which I'm not sure anybody else agrees with,
-but it makes sense to me: If you don't give any rep clauses, then the
-compiler ought to do what's most efficient.  If you care about
-representation more than (the compiler's notion of) efficiency, then
-give a rep clause.  "Predictable representations" is not a goal, if
-there are no rep clauses.
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!from Robert Dewar
-!reference 96-5486.a Robert A Duff 96-4-13>>
-!discussion
-
-(Apparently, Robert has less patience than I do, with the silly headers
-required by the mail server.  And I have very little patience indeed --
-I had to submit some of my recent comments 3 times.  Anyway, I'll be a
-nice guy, and re-submit this for Robert. -- Bob Duff)
-
-Here's Robert's comment:
-
-let me narrow down my size comments to a set of requirements
-
-
-(which are possibly conflicting)
-
-o  it should be possible to write confirming rep clauses for all
-        representation choices made by the compiler
-
-o  the sizes chosen by an Ada 95 compiler should match those of an Ada 83
-        compiler
-
-o  (most important). If the second rule is not met, it should be possible
-        to write rep clauses that cuase the choice to match that of the
-        Ada 83 compiler.
-
-I never liked what was going on with size in RM 95 as you now, but did not
-mind too much as long as 'size could be specified for a subtype as was
-the case till very late on.
-
-It is taking that away that has left RM 95 completely broken with respect
-to the critical third requirement above.
-
-It is merely annoying that the size rules are peculiar, and reflect not
-the best approximation of industry pratice in Ada 83, but rathr the
-behavior of one particular vendors compiler that was in fact not a
-significant presence in the market.
-
-It is much MORE than annoying that there is no easy way to override this
-choice.
-
-At the Paris meeting, we considered it essential that a size clause for
-a first subtype be imposed on all subsequent subtypes, because otherwise
-confirming rep clauses would be impossible.
-
-Ada 95 broke that (why I don't know), but I could live with it because
-I could specify size for a subtype.
-
-At this stage I would like to see:
-
-  o  THat compilers be allowed to specify 'size for other than first
-     subtypes, but not required to do so.
-
-  o  That we simply add to the rules for statically matching subtypes
-     a rule that says that if the sizes are explicitly set and different
-     then the subtypes do not statically match.
-
-I don't care too much if you keep the bizarre rule about sizes happening
-to be different if the subtype happens to statically match the first subtype,
-as long as I can override it.
-
-In fact I don't too much care WHAT is done, since it is only a matter of
-aesthetics, not functionality. If the ARG does not solve this question,
-e.g. in the manner suggested above, then GNAT will simply implement
-'Subtype_Size and solve the problem itself.
-
-This is not a theoretical issue, we are currently not following the RM
-rules, because we know they will break customer code in a manner that
-is not easy to provide work arounds for (note in particular that there
-is no way to easily specify the size of a record component).
-
-P.S. I would in fact be inclined to keep the current RM rules about
-minimum size, consider the following:
-
-  type x is (a,b,c);
-
-in Verdix x'size is 8 or somesuch, BUT Verdix allowed pragma Pack to
-go ahead and pack to 2 bits anyway. This is inconsistent with the Paris
-meeting AI's and with the RM, but in practice, the packing is more
-important than the size, so the RM rules are most practical.
-
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!from Bob Duff
-!reference 96-5487.a Robert A Duff 96-4-13>>
-!discussion
-
-> let me narrow down my size comments to a set of requirements
->
->
-> (which are possibly conflicting)
->
-> o  it should be possible to write confirming rep clauses for all
->       representation choices made by the compiler
-
-Good principle, usually, but we know we've violated it in *some* cases.
-There are two issues:
-
-    1. There are a few (minor) cases in which specifying a certain aspect
-       of representation to a certain value means something different than
-       having an implementation choose that same value by default.  This
-       is bad, and we've minimized it to just a few cases.
-
-    2. There are many cases in which no rep clause is legal, and therefore
-       no confirming rep clause is legal.  For example, rep clauses
-       usually require static-ish things, even though dynamic things
-       can be queried.
-
-There are really two possible priniciples -- confirming rep clauses,
-when legal, should not change semantics, and confirming rep clauses
-should always be legal, and should not change semantics.  The second of
-these was never even close to true for Ada 83, so perhaps it should be
-modified: confirming rep clauses should be legal for the cases that come
-up in practise when interfacing, and should not change semantics.
-
-> o  the sizes chosen by an Ada 95 compiler should match those of an Ada 83
->       compiler
->
-> o  (most important). If the second rule is not met, it should be possible
->       to write rep clauses that cuase the choice to match that of the
->       Ada 83 compiler.
->
-> I never liked what was going on with size in RM 95 as you now, but did not
-> mind too much as long as 'size could be specified for a subtype as was
-> the case till very late on.
->
-> It is taking that away that has left RM 95 completely broken with respect
-> to the critical third requirement above.
->
-> It is merely annoying that the size rules are peculiar, and reflect not
-> the best approximation of industry pratice in Ada 83, but rathr the
-> behavior of one particular vendors compiler that was in fact not a
-> significant presence in the market.
-
-It was the goal of the Ada 95 rules to nail some things down that were
-vague in Ada 83, so that rep clauses could be more portable across (Ada
-95) implementations.  In doing that, it may well be that we've broken
-compatibility with existing Ada 83 implementations.  We could solve this
-problem by going back to the Ada 83 rule, which I paraphrase here: "The
-Size attribute means whatever the implementation wants it to, and it's
-relationship with Unchecked_Conversion, 'Address, and pragma Pack is up
-to the implementation."  I'm being somewhat facetious here -- Robert's
-point is that most implementations agreed with each other, and RM95
-chooses an interpretation that was only chosen by some obscure Ada 83
-implementation.  I'd like to hear some input from compiler vendors here
--- lementations do, and what do think your Ada
-95 implementations ought to do?
-
-> It is much MORE than annoying that there is no easy way to override this
-> choice.
-
-You can override the choice on a per-object and per-component basis, and
-that has a pretty well-defined meaning.  I admit that it's annoying that
-you can't do so on a subtype basis.  The MRT removed that feature for
-technical reasons.  We could decide to add it back in, I suppose, but
-(1) it's a pretty big extension to be adding under the heading
-"interpretations", and (2) we need to find a technically correct way to
-do it.  If we choose to do so, I think we *can* find a technically
-correct way, independent of how the contradiction between 13.1(14) and
-13.3(55) is broken.
-
-> At the Paris meeting, we considered it essential that a size clause for
-> a first subtype be imposed on all subsequent subtypes, because otherwise
-> confirming rep clauses would be impossible.
-
-Unfortunately, Ada 95 allows:
-
-    type T is range 0..1;
-    for T'Size use 1;
-    subtype S is range -1..1;
-
-Clearly, we cannot require that S'Size be 1.
-
-I suppose we could require it for subtypes whose range happens to be
-small enough.
-
-No, that won't work, either, because the range might not be known at
-compile time.  I guess the rule would have to say something about
-staticness.  Or, we could make it all implementation-defined, and let
-implementations worry about how to be compatible with (various) Ada 83
-compilers.
-
-> Ada 95 broke that (why I don't know), but I could live with it because
-> I could specify size for a subtype.
->
-> At this stage I would like to see:
->
->   o  THat compilers be allowed to specify 'size for other than first
->      subtypes, but not required to do so.
-
-Sounds like an extension to me, and not important enough for the ARG to
-bless.  But I could live with it.  If we do it, should we not make some
-sense of the rules?  Or do you expect implementations to deal with it?
-I fear that compilers will simply generate incorrect code for
-conversions of access types (see 13.1(14.a-14.i).  I would prefer to
-either require it or disallow it, rather than allow it.  If we require
-it, of course, we have to make some sense of it.
-
->   o  That we simply add to the rules for statically matching subtypes
->      a rule that says that if the sizes are explicitly set and different
->      then the subtypes do not statically match.
-
-This can work.  But note that it violates the first principle above,
-that confirming rep clauses should work.
-
-> I don't care too much if you keep the bizarre rule about sizes happening
-> to be different if the subtype happens to statically match the first subtype,
-> as long as I can override it.
->
-> In fact I don't too much care WHAT is done, since it is only a matter of
-> aesthetics, not functionality. If the ARG does not solve this question,
-> e.g. in the manner suggested above, then GNAT will simply implement
-> 'Subtype_Size and solve the problem itself.
->
-> This is not a theoretical issue, we are currently not following the RM
-> rules, because we know they will break customer code in a manner that
-> is not easy to provide work arounds for (note in particular that there
-> is no way to easily specify the size of a record component).
-
-Unfortunate, indeed.
-
-> P.S. I would in fact be inclined to keep the current RM rules about
-> minimum size, consider the following:
->
->   type x is (a,b,c);
->
-> in Verdix x'size is 8 or somesuch, BUT Verdix allowed pragma Pack to
-> go ahead and pack to 2 bits anyway. This is inconsistent with the Paris
-> meeting AI's and with the RM, but in practice, the packing is more
-> important than the size, so the RM rules are most practical.
-
-OK, good, we agree on *some* things.  ;-)
-
-Now, don't you think "type X is range 0..2;" is equivalent to the above,
-at the machine level, and should work the same way with respect to
-'Size?
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!reference 96-5487.a Robert A Duff 96-4-13
-!from Bob Duff
-!reference 96-5494.a Robert A Duff 96-4-16>>
-!discussion
-
-Another correction.  Robert Dewar wrote:
-
-> > At the Paris meeting, we considered it essential that a size clause for
-> > a first subtype be imposed on all subsequent subtypes, because otherwise
-> > confirming rep clauses would be impossible.
-
-And I replied:
-
-> Unfortunately, Ada 95 allows:
->
->     type T is range 0..1;
->     for T'Size use 1;
->     subtype S is range -1..1;
-
-I meant "subtype S is T'Base range -1..1;".  My point was that S has a
-                      ^^^^^^
-wider range than the first subtype, so:
-
-> Clearly, we cannot require that S'Size be 1.
->
-> I suppose we could require it for subtypes whose range happens to be
-> small enough.
->
-> No, that won't work, either, because the range might not be known at
-> compile time.  I guess the rule would have to say something about
-> staticness.  Or, we could make it all implementation-defined, and let
-> implementations worry about how to be compatible with (various) Ada 83
-> compilers.
-
-Sorry for the confusion.
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!reference 96-5487.a Robert A Duff 96-4-13
-!from Bob Duff
-!reference 96-5495.a Robert A Duff 96-4-16>>
-!discussion
-
-Robert and I have discussed the Size issue in private e-mail lately.
-(It's a hobby we have, which has taken up most of our spare time in the
-last few years.  ;-) )
-
-Anyway, Robert recommends the following (I'm paraphrasing what he wrote):
-
-  Keep the RM rules (13.3(55)) as they are with respect to default
-  sizes.  Add a rule that the minimum size default rule does not apply
-  to subtypes that happen to statically match the first subtype.
-
-  Implementation Permission: *Allow* implementations to support Size
-  clauses for secondary subtypes.
-
-  Say that two subtypes do not statically match if their Sizes differ
-  (this can be interesting only if one or other of them is a subtype whose
-  Size has been set using the above permission).
-
-I can live with Robert's recommendations.  I won't go *quite* so far as
-to say I *agree* with them -- I don't strongly disagree.  ;-)  How's that
-for wishy-washy?
-
-Robert notes that if the above Implementation Permission is not granted
-by the ARG, then GNAT will implement essentially the same thing, but
-call it by a different name ('Subtype_Size).  This is important, because
-when porting real Ada 83 code to GNAT, such a feature has been needed.
-
-Robert says: P.S. I do not care two hoots about Alignment, I think
-having Alignment as a subtype specific attribute is silly, and GNAT
-ignores the possibility of different subtypes having different
-alignments as much as it can!
-
-Bob says: I agree -- it's not important.  For uniformity, we could
-extend the Impl Permission to Alignment, too.  No big deal.  The only
-important thing, is that if Alignments of subtypes can be different, we
-can't have static matching of those subtypes.  Alignments are largely
-implementation dependent anyway, so this is, I suppose, the
-implementer's problem.
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!reference 96-5487.a Robert A Duff 96-4-13
-!reference 96-5495.a Robert A Duff 96-4-16
-!from Bob Duff 96-4-17
-!reference 96-5498.a Pascal Leroy 96-4-17>>
-!discussion
-
-I suppose we'll have an interesting discussion at the next ARG meeting,
-assuming RBKD is there.  I, for one, strongly disagree with the suggestions
-below, and agree with (the current wording of) AI95-00109
-
-> Anyway, Robert recommends the following (I'm paraphrasing what he wrote):
->
->   Keep the RM rules (13.3(55)) as they are with respect to default
->   sizes.  Add a rule that the minimum size default rule does not apply
->   to subtypes that happen to statically match the first subtype.
->
->   Implementation Permission: *Allow* implementations to support Size
->   clauses for secondary subtypes.
-
-I don't see what is gained by this.  Certainly not portability, since we don't
-_require_ support for such clauses.  The only reason for this permission is
-that it makes it more likely that, if vendors want to support this capability,
-they'll use the same mechanism.  But then we have to assume that vendors are
-not completely stupid: if GNAT for instance supports a 'Subtype_Size
-attribute, and there appears to be good reasons for other vendors to support
-the same capability then it would be sensible for them to use the attribute
-'Subtype_Size.  There are many uniformity issues like that, and we don't have
-to incorporate them in the language: we can just assume that reasonable
-choices will be made.
-
-I suspect that if we put this permission in the language, we'll spend the next
-five years explaining how all the rest of the RM works in the presence of a
-size clause for subtypes.
-
->   Say that two subtypes do not statically match if their Sizes differ
->   (this can be interesting only if one or other of them is a subtype whose
->   Size has been set using the above permission).
-
-Now that violates the separation principle (grab your Ada 83 Rationale and
-read section 15.1 to refresh your memory) and I think it's BAD, and that the
-language is insufficiently broken here to abandon the separation between the
-logical properties and the representation.
-
-> Robert notes that if the above Implementation Permission is not granted
-> by the ARG, then GNAT will implement essentially the same thing, but
-> call it by a different name ('Subtype_Size).  This is important, because
-> when porting real Ada 83 code to GNAT, such a feature has been needed.
-
-I would be curious to see an example of such real Ada 83 code that absolutely
-requires 'Size clauses for subtype.  So far, no convincing example has been
-shown: Robert's Number_Of_Hotels and Number_Of_Companies stuff looked more
-like an example of how to misuse subtypes.
-
-_____________________________________________________________________
-Pascal Leroy                                    +33.1.30.12.09.68
-pleroy@rational.com                             +33.1.30.12.09.66 FAX
-
-****************************************************************
-
-!section 13.3(55)
-!subject Size program
-!reference RM95-13.3(55)
-!reference 96-5497.a Robert A Duff 96-4-17
-!from Bob Duff
-!reference 96-5499.a Robert A Duff 96-4-19>>
-!discussion
-
-Robert Dewar and Pascal Leroy noted some bugs in the program.  Plus I
-noticed a couple myself.  Here's another version, with some bugs fixed.
-
-Sorry.  :-(
-
-Send the results directly to me, and once we've gotten things settled,
-I'll post to ada-comment.
-
-- Bob
-
-with System; use System;
-package Size_Test_Utils is
-
-   procedure Put_Line(S: String);
-   -- Print a line with line number.
-
-   procedure Heading(S: String);
-   -- Print a heading with blank lines around it.
-
-   type Size_In_Bits is range 0..Max_Int;
-   function Img(X: Size_In_Bits) return String;
-   -- Shorthand for Size_In_Bits'Image.
-
-   procedure Check(Subtype_Name: String;
-                   Subtype_Size: Size_In_Bits;
-                   Expected_Size: Size_In_Bits);
-   -- Prints out the subtype's Size.  If Subtype_Size /= Expected_Size,
-   -- notes that fact.
-
-   procedure Check(Subtype_Name: String;
-                   Subtype_Size: Size_In_Bits);
-   -- Same as previous, but used when there's no particular expected size.
-
-   -- The following functions are the same as the corresponding
-   -- procedures.  They return an irrelevant value.  The purpose
-   -- is to be able to call those procedures in a declaration
-   -- context.
-   function Heading(S: String) return Boolean;
-   function Check(Subtype_Name: String;
-                  Subtype_Size: Size_In_Bits;
-                  Expected_Size: Size_In_Bits) return Boolean;
-   function Check(Subtype_Name: String;
-                  Subtype_Size: Size_In_Bits) return Boolean;
-
-   type Longest_Signed_Integer is range Min_Int..Max_Int;
-
-end Size_Test_Utils;
-with Text_IO; use Text_IO;
-package body Size_Test_Utils is
-
-   procedure Put_Line_Number is
-   begin
-      if Col /= 1 then
-         raise Program_Error;
-      end if;
-      Put(Positive_Count'Image(Line));
-      Set_Col(8);
-   end Put_Line_Number;
-
-   procedure Put_Line(S: String) is
-   begin
-      Put_Line_Number;
-      Text_Io.Put_Line(S);
-   end Put_Line;
-
-   procedure Heading(S: String) is
-   begin
-      New_Line;
-      Set_Col(8);
-      Text_Io.Put_Line(S);
-      New_Line;
-   end Heading;
-
-   function Heading(S: String) return Boolean is
-   begin
-      Heading(S);
-      return True;
-   end Heading;
-
-   function Img(X: Size_In_Bits) return String is
-   begin
-      return Size_In_Bits'Image(X);
-   end Img;
-
-   procedure Check(Subtype_Name: String;
-                   Subtype_Size: Size_In_Bits;
-                   Expected_Size: Size_In_Bits) is
-   begin
-      Put_Line_Number;
-      Put(Subtype_Name & "'Size =" & Img(Subtype_Size));
-      if Subtype_Size = Expected_Size then
-         Put(" (ok)");
-      else
-         Put(" (expected" & Img(Expected_Size) & ")");
-      end if;
-      Text_IO.Put_Line(".");
-   end Check;
-
-   procedure Check(Subtype_Name: String;
-                   Subtype_Size: Size_In_Bits) is
-   begin
-      Put_Line_Number;
-      Put(Subtype_Name & "'Size =" & Img(Subtype_Size));
-      Text_IO.Put_Line(".");
-   end Check;
-
-   function Check(Subtype_Name: String;
-                  Subtype_Size: Size_In_Bits;
-                  Expected_Size: Size_In_Bits) return Boolean is
-   begin
-      Check(Subtype_Name, Subtype_Size, Expected_Size);
-      return True;
-   end Check;
-
-   function Check(Subtype_Name: String;
-                  Subtype_Size: Size_In_Bits) return Boolean is
-   begin
-      Check(Subtype_Name, Subtype_Size);
-      return True;
-   end Check;
-
-end Size_Test_Utils;
-with Size_Test_Utils; use Size_Test_Utils;
-pragma Elaborate(Size_Test_Utils);
-package Size_Test_83_Pkg is
-
-   -- This package prints out the 'Size of various subtypes.
-   -- Ada-95-specific code is avoided here.
-   -- The "..._Test" variables are ignored -- they're just there so we
-   -- can call Check in a declaration context.
-
-   package Signed_Integers is
-
-      H1: Boolean := Heading("Signed Integers:");
-
-      type Positive_0 is range 0..0;
-      Positive_0_Test: Boolean :=
-        Check("Positive_0", Positive_0'Size, 0);
-
-      Positive_0_Base_Test: Boolean :=
-        Check("Positive_0'Base", Positive_0'Base'Size);
-
-      type Positive_1 is range 0..1;
-      Positive_1_Test: Boolean :=
-        Check("Positive_1", Positive_1'Size, 1);
-
-      Positive_1_Base_Test: Boolean :=
-        Check("Positive_1'Base", Positive_1'Base'Size);
-
-      type Positive_2 is range 0..2;
-      Positive_2_Test: Boolean :=
-        Check("Positive_2", Positive_2'Size, 2);
-
-      Positive_2_Base_Test: Boolean :=
-        Check("Positive_2'Base", Positive_2'Base'Size);
-
-      type Integer_3 is range -2..2;
-      Integer_3_Test: Boolean :=
-        Check("Integer_3", Integer_3'Size, 3);
-
-      Integer_3_Base_Test: Boolean :=
-        Check("Integer_3'Base", Integer_3'Base'Size);
-
-      type Billion is range -1_000_000_000 .. 1_000_000_000;
-
-      subtype Sub_Pos_0 is Billion range 0..0;
-      Sub_Pos_0_Test: Boolean :=
-        Check("Sub_Pos_0", Sub_Pos_0'Size, 0);
-      subtype Sub_Pos_1 is Billion range 0..1;
-      Sub_Pos_1_Test: Boolean :=
-        Check("Sub_Pos_1", Sub_Pos_1'Size, 1);
-      subtype Sub_Pos_4 is Billion range 0..15;
-      Sub_Pos_4_Test: Boolean :=
-        Check("Sub_Pos_4", Sub_Pos_4'Size, 4);
-      subtype Sub_Int_7 is Billion range -63..63;
-      Sub_Int_7_Test: Boolean :=
-        Check("Sub_Int_7", Sub_Int_7'Size, 7);
-
-   end Signed_Integers;
-   use Signed_Integers;
-
-   package Enums is
-
-      H1: Boolean := Heading("Enums:");
-
-      type Enum_0 is (Red);
-      Enum_0_Test: Boolean :=
-        Check("Enum_0", Enum_0'Size, 0);
-
-      Enum_0_Base_Test: Boolean :=
-        Check("Enum_0'Base", Enum_0'Base'Size, 0);
-
-      type Enum_1 is (Red, Orange);
-      Enum_1_Test: Boolean :=
-        Check("Enum_1", Enum_1'Size, 1);
-
-      Enum_1_Base_Test: Boolean :=
-        Check("Enum_1'Base", Enum_1'Base'Size, 1);
-
-      type Enum_2 is (Red, Orange, Yellow);
-      Enum_2_Test: Boolean :=
-        Check("Enum_2", Enum_2'Size, 2);
-
-      Enum_2_Base_Test: Boolean :=
-        Check("Enum_2'Base", Enum_2'Base'Size, 2);
-
-      type Enum_4 is ('0', '1', '2', '3', '4', '5', '6', '7', '8',
-                      '9', Ten, Eleven, Twelve);
-      Enum_4_Test: Boolean :=
-        Check("Enum_4", Enum_4'Size, 4);
-
-      Enum_4_Base_Test: Boolean :=
-        Check("Enum_4'Base", Enum_4'Base'Size, 4);
-
-      subtype Sub_Enum_0 is Enum_4 range '0'..'0';
-      Sub_Enum_0_Test: Boolean :=
-        Check("Sub_Enum_0", Sub_Enum_0'Size, 0);
-      subtype Sub_Enum_1 is Enum_4 range '0'..'1';
-      Sub_Enum_1_Test: Boolean :=
-        Check("Sub_Enum_1", Sub_Enum_1'Size, 1);
-
-   end Enums;
-   use Enums;
-
-   package Records is
-
-      H1: Boolean := Heading("Records:");
-
-      type Unpacked_Rec is
-         record
-            A: Positive_2;
-            B: Sub_Enum_1;
-         end record;
-      Unpacked_Rec_Test: Boolean :=
-        Check("Unpacked_Rec", Unpacked_Rec'Size);
-
-      type Rec_3 is new Unpacked_Rec;
-      pragma Pack(Rec_3);
-      Rec_3_Test: Boolean :=
-        Check("Rec_3", Rec_3'Size, 3);
-
-      Rec_3_Obj: Rec_3;
-      A_Test: Boolean :=
-        Check("Rec_3_Obj.A", Rec_3_Obj.A'Size, 2);
-      B_Test: Boolean :=
-        Check("Rec_3_Obj.B", Rec_3_Obj.B'Size, 1);
-
-      type Rec_10 is
-         record
-            B1, B2, B3, B4, B5, B6, B7, B8, B9, B10: Boolean;
-         end record;
-      pragma Pack(Rec_10);
-      Rec_10_Test: Boolean :=
-        Check("Rec_10", Rec_10'Size, 10);
-
-      Rec_10_Obj: Rec_10;
-      B1_Test: Boolean :=
-        Check("Rec_10_Obj.B1", Rec_10_Obj.B1'Size, 1);
-
-      type Rec_32 is
-         record
-            X1, X2, X3: Rec_3;
-            X4, X5: Integer_3;
-            Two_Bits: Enum_2;
-            Ten_Bits: Rec_10;
-         end record;
-      pragma Pack(Rec_32);
-      Rec_32_Test: Boolean :=
-        Check("Rec_32", Rec_32'Size, 32);
-
-      Rec_32_Obj: Rec_32;
-      X2_Test: Boolean :=
-        Check("Rec_32_Obj.X2", Rec_32_Obj.X2'Size, 3);
-      X5_Test: Boolean :=
-        Check("Rec_32_Obj.X5", Rec_32_Obj.X5'Size, 3);
-
-   end Records;
-
-private
-
-   procedure Require_Body;
-
-end Size_Test_83_Pkg;
-with System; use System;
-
-package body Size_Test_83_Pkg is
-
-   package Predefined_Stuff is end;
-   package body Predefined_Stuff is
-   begin
-
-      Heading("Predefined Stuff:");
-
-      Put_Line("Min_Int = " & Longest_Signed_Integer'Image(Min_Int));
-      Put_Line("Max_Int = " & Longest_Signed_Integer'Image(Max_Int));
-      Check("Longest_Signed_Integer", Longest_Signed_Integer'Size);
-
-      Put_Line("Storage_Unit = " & Longest_Signed_Integer'Image(Storage_Unit));
-      Check("Address", Address'Size);
-
-      Put_Line("Boolean'First = " & Boolean'Image(Boolean'First) & ".");
-      Put_Line("Boolean'Last = " & Boolean'Image(Boolean'Last) & ".");
-      Check("Boolean", Boolean'Size, 1);
-
-      Put_Line("Integer'First = " & Integer'Image(Integer'First) & ".");
-      Put_Line("Integer'Last = " & Integer'Image(Integer'Last) & ".");
-      Check("Integer", Integer'Size);
-
-      Put_Line("Natural'First = " & Natural'Image(Natural'First) & ".");
-      Put_Line("Natural'Last = " & Natural'Image(Natural'Last) & ".");
-      Check("Natural", Natural'Size);
-
-      Put_Line("Positive'First = " & Positive'Image(Positive'First) & ".");
-      Put_Line("Positive'Last = " & Positive'Image(Positive'Last) & ".");
-      Check("Positive", Positive'Size);
-
-      Put_Line("Character'First = " & Character'Image(Character'First) & ".");
-      Put_Line("Character'Last = " & Character'Image(Character'Last) & ".");
-      Check("Character", Character'Size, 8);
-   end Predefined_Stuff;
-
-   procedure Require_Body is
-   begin
-      null;
-   end Require_Body;
-
-end Size_Test_83_Pkg;
-with Size_Test_Utils; use Size_Test_Utils;
-with Size_Test_83_Pkg; use Size_Test_83_Pkg;
-
-pragma Elaborate(Size_Test_Utils);
-pragma Elaborate(Size_Test_83_Pkg);
-
-package Size_Clause_83_Pkg is
-
-   -- Same as Size_Test_83_Pkg, except this package concentrates on cases
-   -- where the Size is specified in an attribute_definition_clause.
-   -- Each subtype Foo_Spec corresponds to subtype Foo from
-   -- Size_Test_83_Pkg.  The declaration of Foo_Spec and Foo are
-   -- the same, except that Foo_Spec has a Size clause.
-
-   use Size_Test_83_Pkg.Signed_Integers;
-   use Size_Test_83_Pkg.Enums;
-   use Size_Test_83_Pkg.Records;
-
-   package Signed_Integers is
-
-      H1: Boolean := Heading("Signed Integers with Size Clauses:");
-
-      type Positive_0_Spec is range 0..0;
-      for Positive_0_Spec'Size use 0;
-      Positive_0_Spec_Test: Boolean :=
-        Check("Positive_0_Spec", Positive_0_Spec'Size, 0);
-
-      Positive_0_Spec_Base_Test: Boolean :=
-        Check("Positive_0_Spec'Base", Positive_0_Spec'Base'Size);
-
-      type Positive_1_Spec is range 0..1;
-      for Positive_1_Spec'Size use 1;
-      Positive_1_Spec_Test: Boolean :=
-        Check("Positive_1_Spec", Positive_1_Spec'Size, 1);
-
-      Positive_1_Spec_Base_Test: Boolean :=
-        Check("Positive_1_Spec'Base", Positive_1_Spec'Base'Size);
-
-      type Positive_2_Spec is range 0..2;
-      for Positive_2_Spec'Size use 2;
-      Positive_2_Spec_Test: Boolean :=
-        Check("Positive_2_Spec", Positive_2_Spec'Size, 2);
-
-      Positive_2_Spec_Base_Test: Boolean :=
-        Check("Positive_2_Spec'Base", Positive_2_Spec'Base'Size);
-
-      type Integer_3_Spec is range -2..2;
-      for Integer_3_Spec'Size use 3;
-      Integer_3_Spec_Test: Boolean :=
-        Check("Integer_3_Spec", Integer_3_Spec'Size, 3);
-
-      Integer_3_Spec_Base_Test: Boolean :=
-        Check("Integer_3_Spec'Base", Integer_3_Spec'Base'Size);
-
-      type Billion_Spec is range -1_000_000_000 .. 1_000_000_000;
-      for Billion_Spec'Size use 31;
-      Billion_Spec_Test: Boolean :=
-        Check("Billion_Spec", Billion_Spec'Size, 31);
-
-      subtype Sub_Pos_0_Spec is Billion_Spec range 0..0;
-      Sub_Pos_0_Spec_Test: Boolean :=
-        Check("Sub_Pos_0_Spec", Sub_Pos_0_Spec'Size, 0);
-      subtype Sub_Pos_1_Spec is Billion_Spec range 0..1;
-      Sub_Pos_1_Spec_Test: Boolean :=
-        Check("Sub_Pos_1_Spec", Sub_Pos_1_Spec'Size, 1);
-      subtype Sub_Pos_4_Spec is Billion_Spec range 0..15;
-      Sub_Pos_4_Spec_Test: Boolean :=
-        Check("Sub_Pos_4_Spec", Sub_Pos_4_Spec'Size, 4);
-      subtype Sub_Int_7_Spec is Billion_Spec range -63..63;
-      Sub_Int_7_Spec_Test: Boolean :=
-        Check("Sub_Int_7_Spec", Sub_Int_7_Spec'Size, 7);
-
-   end Signed_Integers;
-   use Signed_Integers;
-
-   package Enums is
-
-      H1: Boolean := Heading("Enums with Size Clauses:");
-
-      type Enum_0_Spec is (Red);
-      for Enum_0_Spec'Size use 0;
-      Enum_0_Spec_Test: Boolean :=
-        Check("Enum_0_Spec", Enum_0_Spec'Size, 0);
-
-      Enum_0_Spec_Base_Test: Boolean :=
-        Check("Enum_0_Spec'Base", Enum_0_Spec'Base'Size, 0);
-
-      type Enum_1_Spec is (Red, Orange);
-      for Enum_1_Spec'Size use 1;
-      Enum_1_Spec_Test: Boolean :=
-        Check("Enum_1_Spec", Enum_1_Spec'Size, 1);
-
-      Enum_1_Spec_Base_Test: Boolean :=
-        Check("Enum_1_Spec'Base", Enum_1_Spec'Base'Size, 1);
-
-      type Enum_2_Spec is (Red, Orange, Yellow);
-      for Enum_2_Spec'Size use 2;
-      Enum_2_Spec_Test: Boolean :=
-        Check("Enum_2_Spec", Enum_2_Spec'Size, 2);
-
-      Enum_2_Spec_Base_Test: Boolean :=
-        Check("Enum_2_Spec'Base", Enum_2_Spec'Base'Size, 2);
-
-      type Enum_4_Spec is ('0', '1', '2', '3', '4', '5', '6', '7', '8',
-                      '9', Ten, Eleven, Twelve);
-         for Enum_4_Spec'Size use 4;
-      Enum_4_Spec_Test: Boolean :=
-        Check("Enum_4_Spec", Enum_4_Spec'Size, 4);
-
-      Enum_4_Spec_Base_Test: Boolean :=
-        Check("Enum_4_Spec'Base", Enum_4_Spec'Base'Size, 4);
-
-      subtype Sub_Enum_0_Spec is Enum_4_Spec range '0'..'0';
-      Sub_Enum_0_Spec_Test: Boolean :=
-        Check("Sub_Enum_0_Spec", Sub_Enum_0_Spec'Size, 0);
-      subtype Sub_Enum_1_Spec is Enum_4_Spec range '0'..'1';
-      Sub_Enum_1_Spec_Test: Boolean :=
-        Check("Sub_Enum_1_Spec", Sub_Enum_1_Spec'Size, 1);
-
-      type Six_Bit_Enum_4_Spec is ('0', '1', '2', '3', '4', '5', '6', '7', '8',
-                                '9', Ten, Eleven, Twelve);
-         for Six_Bit_Enum_4_Spec'Size use 6; -- Non-default Size
-      Six_Bit_Enum_4_Spec_Test: Boolean :=
-        Check("Six_Bit_Enum_4_Spec", Six_Bit_Enum_4_Spec'Size, 6);
-
-      Six_Bit_Enum_4_Spec_Base_Test: Boolean :=
-        Check("Six_Bit_Enum_4_Spec'Base", Six_Bit_Enum_4_Spec'Base'Size, 6);
-
-      subtype Sub_Six_Bit_Enum_0_Spec is Six_Bit_Enum_4_Spec range '0'..'0';
-      Sub_Six_Bit_Enum_0_Spec_Test: Boolean :=
-        Check("Sub_Six_Bit_Enum_0_Spec", Sub_Six_Bit_Enum_0_Spec'Size, 0);
-      subtype Sub_Six_Bit_Enum_1_Spec is Six_Bit_Enum_4_Spec range '0'..'1';
-      Sub_Six_Bit_Enum_1_Spec_Test: Boolean :=
-        Check("Sub_Six_Bit_Enum_1_Spec", Sub_Six_Bit_Enum_1_Spec'Size, 1);
-
-      subtype Sub_Six_Bit_Enum_6_Spec is Six_Bit_Enum_4_Spec range '0'..Twelve;
-      Sub_Six_Bit_Enum_6_Spec_Test: Boolean :=
-        Check("Sub_Six_Bit_Enum_6_Spec", Sub_Six_Bit_Enum_6_Spec'Size, 6);
-
-   end Enums;
-   use Enums;
-
-   package Records is
-
-      H1: Boolean := Heading("Records with Size Clauses:");
-
-      type Unpacked_Rec_Spec is
-         record
-            A: Positive_2_Spec;
-            B: Sub_Enum_1_Spec;
-         end record;
-      Unpacked_Rec_Spec_Test: Boolean :=
-        Check("Unpacked_Rec_Spec", Unpacked_Rec'Size);
-
-      type Rec_3_Spec is new Unpacked_Rec_Spec;
-      pragma Pack(Rec_3_Spec);
-      for Rec_3_Spec'Size use 3;
-      Rec_3_Spec_Test: Boolean :=
-        Check("Rec_3_Spec", Rec_3_Spec'Size, 3);
-
-      Rec_3_Spec_Obj: Rec_3_Spec;
-      A_Test: Boolean :=
-        Check("Rec_3_Spec_Obj.A", Rec_3_Spec_Obj.A'Size, 2);
-      B_Test: Boolean :=
-        Check("Rec_3_Spec_Obj.B", Rec_3_Spec_Obj.B'Size, 1);
-
-      type Rec_10_Spec is
-         record
-            B1, B2, B3, B4, B5, B6, B7, B8, B9, B10: Boolean;
-         end record;
-      pragma Pack(Rec_10_Spec);
-      for Rec_10_Spec'Size use 10;
-      Rec_10_Spec_Test: Boolean :=
-        Check("Rec_10_Spec", Rec_10_Spec'Size, 10);
-
-      Rec_10_Spec_Obj: Rec_10_Spec;
-      B1_Test: Boolean :=
-        Check("Rec_10_Spec_Obj.B1", Rec_10_Spec_Obj.B1'Size, 1);
-
-      type Rec_32_Spec is
-         record
-            X1, X2, X3: Rec_3_Spec;
-            X4, X5: Integer_3_Spec;
-            Two_Bits: Enum_2_Spec;
-            Ten_Bits: Rec_10_Spec;
-         end record;
-      pragma Pack(Rec_32_Spec);
-      for Rec_32_Spec'Size use 32;
-      Rec_32_Spec_Test: Boolean :=
-        Check("Rec_32_Spec", Rec_32_Spec'Size, 32);
-
-      Rec_32_Spec_Obj: Rec_32_Spec;
-      X2_Test: Boolean :=
-        Check("Rec_32_Spec_Obj.X2", Rec_32_Spec_Obj.X2'Size, 3);
-      X5_Test: Boolean :=
-        Check("Rec_32_Spec_Obj.X5", Rec_32_Spec_Obj.X5'Size, 3);
-
-   end Records;
-
-end Size_Clause_83_Pkg;
-with Size_Test_Utils; use Size_Test_Utils;
-with Size_Test_83_Pkg; use Size_Test_83_Pkg;
-with Size_Clause_83_Pkg; use Size_Clause_83_Pkg;
-
-pragma Elaborate(Size_Test_Utils);
-pragma Elaborate(Size_Test_83_Pkg);
-pragma Elaborate(Size_Clause_83_Pkg);
-
-package Size_Test_95_Pkg is
-
-   -- Same purpose as Size_Test_83_Pkg and Size_Clause_83_Pkg,
-   -- but we put all the Ada-95-only declarations here.
-
-   package Signed_Integers is
-
-      H1: Boolean := Heading("Ada 95 Signed Integers:");
-
-      use Size_Test_83_Pkg.Signed_Integers;
-      use Size_Clause_83_Pkg.Signed_Integers;
-
-      subtype Positive_0_B is
-        Positive_0'Base range -Positive_0'Last..Positive_0'Last;
-      Positive_0_B_Test: Boolean :=
-        Check("Positive_0_B", Positive_0_B'Size, 0);
-
-      subtype Positive_0_BB is Positive_0'Base range 0..Positive_0'Last;
-      Positive_0_BB_Test: Boolean :=
-        Check("Positive_0_BB", Positive_0_BB'Size, 0);
-
-      subtype Positive_0_Spec_B is
-        Positive_0_Spec'Base range -Positive_0_Spec'Last..Positive_0_Spec'Last;
-      Positive_0_Spec_B_Test: Boolean :=
-        Check("Positive_0_Spec_B", Positive_0_Spec_B'Size, 0);
-
-      subtype Positive_0_Spec_BB is
-        Positive_0_Spec'Base range 0..Positive_0_Spec'Last;
-      Positive_0_Spec_BB_Test: Boolean :=
-        Check("Positive_0_Spec_BB", Positive_0_Spec_BB'Size, 0);
-
-      subtype Positive_1_B is
-        Positive_1'Base range -Positive_1'Last..Positive_1'Last;
-      Positive_1_B_Test: Boolean :=
-        Check("Positive_1_B", Positive_1_B'Size, 2);
-
-      subtype Positive_1_BB is Positive_1'Base range 0..Positive_1'Last;
-      Positive_1_BB_Test: Boolean :=
-        Check("Positive_1_BB", Positive_1_BB'Size, 1);
-
-      subtype Positive_1_Spec_B is
-        Positive_1_Spec'Base range -Positive_1_Spec'Last..Positive_1_Spec'Last;
-      Positive_1_Spec_B_Test: Boolean :=
-        Check("Positive_1_Spec_B", Positive_1_Spec_B'Size, 2);
-
-      subtype Positive_1_Spec_BB is
-        Positive_1_Spec'Base range 0..Positive_1_Spec'Last;
-      Positive_1_Spec_BB_Test: Boolean :=
-        Check("Positive_1_Spec_BB", Positive_1_Spec_BB'Size, 1);
-
-      subtype Positive_2_B is
-        Positive_2'Base range -Positive_2'Last..Positive_2'Last;
-      Positive_2_B_Test: Boolean :=
-        Check("Positive_2_B", Positive_2_B'Size, 3);
-
-      subtype Positive_2_BB is Positive_2'Base range 0..Positive_2'Last;
-      Positive_2_BB_Test: Boolean :=
-        Check("Positive_2_BB", Positive_2_BB'Size, 2);
-
-      subtype Positive_2_Spec_B is
-        Positive_2_Spec'Base range -Positive_2_Spec'Last..Positive_2_Spec'Last;
-      Positive_2_Spec_B_Test: Boolean :=
-        Check("Positive_2_Spec_B", Positive_2_Spec_B'Size, 3);
-
-      subtype Positive_2_Spec_BB is
-        Positive_2_Spec'Base range 0..Positive_2_Spec'Last;
-      Positive_2_Spec_BB_Test: Boolean :=
-        Check("Positive_2_Spec_BB", Positive_2_Spec_BB'Size, 2);
-
-      subtype Integer_3_B is
-        Integer_3'Base range -Integer_3'Last..Integer_3'Last;
-      Integer_3_B_Test: Boolean :=
-        Check("Integer_3_B", Integer_3_B'Size, 3);
-
-      subtype Integer_3_BB is Integer_3'Base range 0..Integer_3'Last;
-      Integer_3_BB_Test: Boolean :=
-        Check("Integer_3_BB", Integer_3_BB'Size, 2);
-
-      subtype Integer_3_Spec_B is
-        Integer_3'Base range -Integer_3'Last..Integer_3'Last;
-      Integer_3_Spec_B_Test: Boolean :=
-        Check("Integer_3_Spec_B", Integer_3_Spec_B'Size, 3);
-
-      subtype Integer_3_Spec_BB is Integer_3'Base range 0..Integer_3'Last;
-      Integer_3_Spec_BB_Test: Boolean :=
-        Check("Integer_3_Spec_BB", Integer_3_Spec_BB'Size, 2);
-
-   end Signed_Integers;
-
-   package Modular_Integers is
-
-      H1: Boolean := Heading("Ada 95 Modular Integers:");
-
-      type Mod_0 is mod 2**0;
-      Mod_0_Test: Boolean :=
-        Check("Mod_0", Mod_0'Size, 0);
-
-      Mod_0_Base_Test: Boolean :=
-        Check("Mod_0'Base", Mod_0'Base'Size);
-
-      type Mod_1 is mod 2**1;
-      Mod_1_Test: Boolean :=
-        Check("Mod_1", Mod_1'Size, 1);
-
-      Mod_1_Base_Test: Boolean :=
-        Check("Mod_1'Base", Mod_1'Base'Size);
-
-      type Mod_2 is mod 2**2;
-      Mod_2_Test: Boolean :=
-        Check("Mod_2", Mod_2'Size, 2);
-
-      Mod_2_Base_Test: Boolean :=
-        Check("Mod_2'Base", Mod_2'Base'Size);
-
-      type Mod_32 is mod 2**32;
-      Mod_32_Test: Boolean :=
-        Check("Mod_32", Mod_32'Size, 32);
-
-      Mod_32_Base_Test: Boolean :=
-        Check("Mod_32'Base", Mod_32'Base'Size);
-
-      type Million is mod 1_000_000;
-
-      subtype Sub_Mod_0 is Million range 0..0;
-      Sub_Mod_0_Test: Boolean :=
-        Check("Sub_Mod_0", Sub_Mod_0'Size, 0);
-      subtype Sub_Mod_1 is Million range 0..1;
-      Sub_Mod_1_Test: Boolean :=
-        Check("Sub_Mod_1", Sub_Mod_1'Size, 1);
-      subtype Sub_Mod_4 is Million range 0..15;
-      Sub_Mod_4_Test: Boolean :=
-        Check("Sub_Mod_4", Sub_Mod_4'Size, 4);
-      subtype Sub_Int_7 is Million range 0..100;
-      Sub_Int_7_Test: Boolean :=
-        Check("Sub_Int_7", Sub_Int_7'Size, 7);
-
-   end Modular_Integers;
-
-private
-
-   procedure Require_Body;
-
-end Size_Test_95_Pkg;
-with System; use System;
-with System.Storage_Elements; use System.Storage_Elements;
-
-package body Size_Test_95_Pkg is
-
-   package Predefined_Stuff is end;
-   package body Predefined_Stuff is
-
-      H1: Boolean := Heading("Ada 95 Predefined Stuff:");
-
-      type Longest_Binary_Modular is mod Max_Binary_Modulus;
-      type Longest_Nonbinary_Modular is mod Max_Nonbinary_Modulus;
-      Max_Binary_Modulus_Minus_One: constant := Max_Binary_Modulus - 1;
-      Max_Nonbinary_Modulus_Minus_One: constant := Max_Nonbinary_Modulus - 1;
-   begin
-
-      Put_Line("Max_Binary_Modulus = " &
-        Longest_Binary_Modular'Image(Max_Binary_Modulus_Minus_One) & " + 1");
-      Check("Longest_Binary_Modular", Longest_Binary_Modular'Size);
-
-      Put_Line("Max_Nonbinary_Modulus = " &
-        Longest_Nonbinary_Modular'Image(Max_Nonbinary_Modulus_Minus_One) &
-               " + 1");
-      Check("Longest_Nonbinary_Modular", Longest_Nonbinary_Modular'Size);
-
-      Put_Line("Word_Size = " & Longest_Signed_Integer'Image(Word_Size));
-
-      Check("Storage_Element", Storage_Element'Size, Storage_Unit);
-
-      Put_Line("Wide_Character'First = " &
-        Wide_Character'Image(Wide_Character'First) & ".");
-      Put_Line("Wide_Character'Last = " &
-               Wide_Character'Image(Wide_Character'Last) & ".");
-      Check("Wide_Character", Wide_Character'Size, 16);
-   end Predefined_Stuff;
-
-   procedure Require_Body is
-   begin
-      null;
-   end Require_Body;
-
-end Size_Test_95_Pkg;
--- hat calls the Ada 83 parts of the Size test.
--- 
-
--- ing elaboration of the Size_..._Pkg packages.
-
-with Text_IO; use Text_IO;
-with Size_Test_83_Pkg;
-with Size_Clause_83_Pkg;
-procedure Size_Test_83 is
-begin
-   New_Line;
-   Put_Line("[Size_Test_83 done.]");
-end Size_Test_83;
--- hat calls the Ada 83 *and* Ada 95 parts
--- 
--- 
-
--- ing elaboration of the Size_..._Pkg packages.
-
-with Text_IO; use Text_IO;
-with Size_Test_83_Pkg;
-with Size_Clause_83_Pkg;
-with Size_Test_95_Pkg;
-procedure Size_Test_95 is
-begin
-   New_Line;
-   Put_Line("[Size_Test_95 done.]");
-end Size_Test_95;
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!reference 96-5487.a Bob Duff
-!from Randy Brukardt (RR Software)
-!reference 96-5500.a rbrukardt@BIX.com 96-4-20>>
-
->It was the goal of the Ada 95 rules to nail some things down that were
->vague in Ada 83, so that rep clauses could be more portable across (Ada
->95) implementations.  In doing that, it may well be that we've broken
->compatibility with existing Ada 83 implementations.  We could solve this
->problem by going back to the Ada 83 rule, which I paraphrase here: "The
->Size attribute means whatever the implementation wants it to, and it's
->relationship with Unchecked_Conversion, 'Address, and pragma Pack is up
->to the implementation."  I'm being somewhat facetious here -- Robert's
->point is that most implementations agreed with each other, and RM95
->chooses an interpretation that was only chosen by some obscure Ada 83
->implementation.  I'd like to hear some input from compiler vendors here
->-- what did your Ada 83 implementations do, and what do think your Ada
->95 implementations ought to do?
-
-Well, I've been intending to get into this discussion since it started last
-Fall, but never could figure out where to begin.  Bob has given me an
-appropriate starting place.
-
-Ada 83 'Size was very vague.  At the time we were implementing it, there
-were no ACVC tests, so we could not tell what the ACVC thought the intent
-was.  Nor had the ARG said anything on the matter.  We concluded that 'Size
-was determined on a type (not subtype) basis, and that it reflected the
-size of a stand-alone object.  (Note that this conclusion is exactly opposite
-what Ada 95 chose!)  We made a one exception to this conclusion: 'Size for
-a subtype with a radically different representation (such as a constrained
-array vs. an unconstrained array) would be different -- and that was largely
-a result of ACVC tests expecting that String(1..10)'Size = 10 * Character'Size
-(a requirement we found out about only after we had finished implementing
-'Size, and one later removed from the tests, I think).
-
-It was clear to use that declarations like the following all had the same
-'Size, since 'Size was determined on a type basis:
-        Type A Is Range -20000 .. 50000; -- 'Size = 32 = 'Base'Size.
-        Subtype B Is Range 0 .. 20000; -- 'Size is still 32.
-        Subtype C Is Range 0 .. 200; -- 'Size is still 32.
-
-However, ACVC tests required that components of subtype C (for example) could
-be stored in 8 bits.  That led us to two more conclusions: 'Size has no
-effect on what rep. clauses can be used, and the components need to be handled
-differently than stand-alone objects.  (Up to this point, they both were
-handled the same way).
-
-We also thought that 'Size on objects was intended to use discriminant/bounds
-values to return the actual size.  That made some complex code, but of course
-it was never tested (and probably isn't useful, either).
-
-Eventually, we concluded that 'Size had effect on anything, and was just
-another useless Ada 83 construct.
-
-Our final implementation of 'Size looks like:
-        1) 'Size can be confirmed on all types.
-        2) 'Size can be set on discrete types only.  The 'Size chosen will be
-           used to select a base type representation, and in (unsigned) cases,
-           a possibly different in memory representation.
-           We considered allowing 'Size to be set for some other types.
-           In particular, we considered using a specified size to select the
-           representation of a pointer (similarly to what the Ada 95 compiler
-           for the U2200 does with Convention).  We also considered using
-           specified sizes for record types.  The latter was not considered
-           important, and the former (long pointers directly supported by
-           the compiler) never was implemented.
-        3) 'Size is stored in the symbol table to be returned on a user
-           query.
-        4) 'Size is passed at runtime to generic units (remember we use
-           universal sharing as our generic model), mainly so it can be
-           returned on a query.  [This was done because of ACVC tests.
-           We tried to get the ARG and AVO not require this stupidity in this
-           case, but were unsuccessful.]
-        5) The compiler stores a stand-alone object size (unfortunately called
-           'Length', that is a length of storage units), which is used for
-           virutally all important purposes.
-        6) 'Size for objects starts with the stand-alone size, then adds
-           the size of any indirect components, based on their actual sizes.
-           'Size for composite types uses the maximum size of any indirect
-           components added to the stand-alone size (when it is not specified;
-           note that it cannot be specified for any composite type containing
-           indirect components, since such components are not statically
-           constrained).
-        7) Pack and rep. clauses use a minimum size calculated on the fly for
-           a subtype (for discrete types).  This is essentially the same as
-           the Ada 95 definition of 'Size.  Composite types always use 'Size =
-           stand-alone size, and smaller components are not supported.
-        8) Unchecked_Conversion uses the stand-alone object size for size
-           matching.  Components are always converted to the stand-alone
-           size when read, so that is the most appropriate.  This probably
-           is why I always was discussing the difference between register and
-           memory-based models for Unchecked_Conversion, which no one else
-           ever seemed to understand.
-
-Because of this model, I was always adamantly opposed to 'Size being specifiable
-on subtypes.  With the current thinking about these models, I don't think there
-is any problem with 'Size specification on discrete subtypes (because 'Size
-does not affect stand-alone objects).  But I still don't anything to do
-with subtypes having different sizes for composite types.
-
-I do agree with Robert that it should be possible for an Ada 95 compiler to
-layout memory the same as the Ada 83 compiler did.  Certainly we want this
-to be the case for the vast majority of types in the absence of representation
-clauses.  I include Pack in representation clauses; I cannot imagine a situation
-where our Ada 95 compiler would get the same results for Pack that it did for
-our Ada 83 compiler -- simply because our Ada 83 compiler never implemented
-Pack!
-
-I guess I never really understood the root issue here.  "Obviously", a compiler
-would store subtypes with the underlying stand-alone object "length"; 'Size
-has no effect on the representation of a pointed-at-object.  "Obviously",
-most such conversions would work.  (As usual, the conversions themselves are
-uninteresting, but 'Access is defined in terms of conversion, so that the
-rule does matter.)  The problem, of course, from a language definition point
-of view is that we do want to allow compilers to use different representations
-for stand-alone objects of different subtypes.  Thus, I suppose we get the
-mess.
-
-In any case, I can live with Robert's recommendations.  (See the following
-messages for other issues).
-
-BTW, when perusing the ARM, I cannot find any mention of the recommended
-level of support for specifying 'Size.  It says a lot about the meaning of
-'Size, but not about what (sub)types allow specification.  Have I missed
-something, or are we all discussing the wrong issue???
-
-                                Randy Brukardt
-
-****************************************************************
-
-!section 13.2(08)
-!subject By-reference types and packing
-!reference RM95-13.2(8)
-!reference RM95-13.2(9)
-!reference RM95-13.3(72)
-!reference RM95-13.3(73)
-!reference 96-5463.a Bob Duff
-!from Randy Brukardt (RR Software)
-!reference 96-5501.a rbrukardt@BIX.com 96-4-20>>
-
-The referenced message contains examples of packing.  This brings up a question
-in my mind.
-
-    type Device_Info is
-        record
-            In_Ready: Boolean;
-            Out_Ready: Boolean;
-        end record;
-    pragma Pack(Device_Info); -- Device_Info'Size = 2.
-
-    type Device_Array is Array (1..4) of Device_Info;
-    for Device_Array'Component_Size use 2;
-
-    Dev : Device_Array;
-
-    procedure Operate (A : In Out Device_Info);
-
-This example appears to be legal.
-
-Consider the call:
-        Operate (Dev(2));
-
-Since the second component of Dev is packed, it will start at bit 2; certainly
-it will not start at a storage unit boundary, and will not be directly
-addressible.
-
-That means that the item almost certainly will be passed by copy.  Either it
-will be directly passed by copy, or it will be passed by reference via a
-copy made at the call site.  It can be passed by reference only if all
-parameters of that type are passed using a bit pointer of some sort.
-
-Now, consider that a record such as Device_Info can be made into a by-reference
-type in at least three ways:
-        1) By explicitly declaring it limited.  (This is probably pathological).
-        2) By applying pragma Atomic to it.
-        3) By applying pragma Volatile to it.
-The last two are certainly possible in real programs (which I hopefully
-illustrated by my choice of names).
-
-A by-reference type does not allow pass by copy.  Therefore, a bit pointer
-must be used to pass the type.  This is quite expensive, and I believe was
-not intended.  Worse, a side effect of requiring that in even a single
-unlikely case, is that an implementation using universal generic code sharing
-will be forced to pass ALL generic private and many generic derived and array
-types with bit pointers.
-
-Have I missed a rule somewhere which states that by reference components are
-treated similarly to aliased components?  Come to think of it, I can't
-find any rule which says that
-
-    type Device_Array is Array (1..8) of Aliased Boolean;
-    for Device_Array'Component_Size use 1;
-
-is not required, either.
-
-(Of course, we can avoid the problem by not supporting the system programming
-annex, but I doubt that is a good long-term plan...)
-
-                        Randy Brukardt
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!reference 96-5487.a Bob Duff
-!reference 96-5500.a rbrukardt@BIX.com 96-4-20
-!reference 96-5503.a Robert A Duff 96-4-21>>
-
-> BTW, when perusing the ARM, I cannot find any mention of the recommended
-> level of support for specifying 'Size.  It says a lot about the meaning of
-> 'Size, but not about what (sub)types allow specification.  Have I missed
-> something, or are we all discussing the wrong issue???
-
-For subtypes, look at the last sentence of 13.3(55), "If such a subtype
-is a first subtype, then an implementation should support a specified
-Size for it that reflects this representation."  13.3(53) is also
-relevant.
-
-For objects, there's 13.3(43):
-
-   43  A Size clause should be supported for an object if the specified
-       Size is at least as large as its subtype's Size, and corresponds
-       to a size in storage elements that is a multiple of the object's
-       Alignment (if the Alignment is nonzero).
-
-- Bob
-
-****************************************************************
-
-!section 13.2(08)
-!subject By-reference types and packing
-!reference RM95-13.2(8)
-!reference RM95-13.2(9)
-!reference RM95-13.3(72)
-!reference RM95-13.3(73)
-!reference 96-5463.a Bob Duff
-!reference 96-5501.a rbrukardt@BIX.com 96-4-20
-!from Bob Duff
-!reference 96-5504.a Robert A Duff 96-4-21>>
-
-> Now, consider that a record such as Device_Info can be made into a by-reference
-> type in at least three ways:
->       1) By explicitly declaring it limited.  (This is probably pathological).
->       2) By applying pragma Atomic to it.
->       3) By applying pragma Volatile to it.
-> The last two are certainly possible in real programs (which I hopefully
-> illustrated by my choice of names).
-
-It is certainly true that there is no intention of requiring
-pass-by-reference to be implemented using some sort of bit-field
-pointers.  Clearly, if any of the above are true, then the
-implementation should allocate things on a storage unit boundary,
-despite pragma Pack.  In fact, some implementations might require 4-byte
-boundaries, or something, which should be allowed.
-
-The same goes for "aliased" things.
-
-- Bob
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!reference 96-5487.a Bob Duff
-!reference 96-5500.a rbrukardt@BIX.com 96-4-20
-!reference 96-5503.a Robert A Duff 96-4-21
-!from Randy Brukardt 96-4-23
-!reference 96-5507.a Ian Goldberg  96-4-23>>
-!discussion
-
->> BTW, when perusing the ARM, I cannot find any mention of the =
-recommended
->> level of support for specifying 'Size.  It says a lot about the =
-meaning of
->> 'Size, but not about what (sub)types allow specification.  Have I =
-missed
->> something, or are we all discussing the wrong issue???
-
->For subtypes, look at the last sentence of 13.3(55), "If such a subtype
->is a first subtype, then an implementation should support a specified
->Size for it that reflects this representation."  13.3(53) is also
->relevant.
-
-Therefore, the only required support for specification of 'Size is for =
-discrete and fixed point types, and only a single size is required.  =
-That means any specification of 'Size on a composite, access, or float =
-type is at the whim of the implementor, as is specification to =
-(multiples of) the storage unit size.
-
-Thus, most of the examples we have been discussing are relavant only in =
-terms of permitted support, as opposed to required support.
-
-****************************************************************
-
-!section 13.1(14)
-!subject Re: Dewar's comments on the SIZE problem and Issue
-!reference RM95-13.1(14)
-!reference RM95-13.3(55)
-!reference 96-5486.a Robert Dewar
-!reference 96-5487.a Bob Duff
-!reference 96-5500.a rbrukardt@BIX.com 96-4-20
-!reference 96-5503.a Robert A Duff 96-4-21
-!reference 96-5507.a Ian Goldberg  96-4-23
-!from Bob Duff
-!reference 96-5526.a Robert A Duff 96-4-29>>
-!discussion
-
-> Thus, most of the examples we have been discussing are relavant only in =
-> terms of permitted support, as opposed to required support.
-
-Yes.  The question is: should more support be required and/or
-recommended?
-
-Note that 13.2(7-9) could, depending on how you read it, be considered
-to place further requirements on implementations, in addition to
-13.3(55).
-
-- Bob
-
-P.S. Your mail software seems garble things, e.g. it puts strange "="
-signs all over, which is kind of annoying.  Especially in the output of
-the example program, where it changes "=" to "=3D".
-
-****************************************************************
-
-!section 13.03(42)
-!subject Comments to AIs regarding 'Size
-!reference AI95-00051
-!reference AI95-00109
-!from Ken Garlington 96-05-13
-!keywords Size
-!reference 96-5552.a Ken Garlington  96-5-13>>
-!discussion
-
-AI95-00051: It seems to me that the restriction on 'Size for fixed and
-floating point values is excessive, and that the justification could
-easily apply to any value (e.g., a compiler/architecture could choose a
-"special" representation for integers, and stay within the language).
-
-Suggest replacing the current proposal for fixed/floating point with the
-following:
-
-  - For fixed point, up to the Size of the largest fixed point
-    type supported by the implementation.
-
-  - For floating point, up to the Size of the largest floating point
-    type supported by the implementation.
-
-For example, if an architecture had two "special" representations for
-floating point (e.g., normal and extended floating point on a
-MIL-STD-1750), a sufficiently large Size for a normal floating point
-would cause the compiler to generate an extended floating point
-representation. If there was only one representation for floating point,
-then Size would have no effect. This also seems consistent with the
-"minimal size" rule, in that a special representation for a number would
-force the allocation of a certain number of bits regardless of Size.
-
-The suggested alternative seems more consistent with the other rules,
-while preserving what I think was the intent of the current proposal.
-
-(By the way, I assume that someone has made sure these interpretations
-regarding objects have also been carried forward to types where
-applicable...)
-
-AI95-00109/01:  I am strongly in favor of the Robert Dewar position
-described in the commentary, including his "Ulterior Motive".
-
-
-****************************************************************
-
-!section 13.3(42)
-!subject Comments to AIs regarding 'Size
-!reference AI95-00051
-!reference AI95-00109
-!reference 96-5552.a Ken Garlington  96-5-13
-!from Robert Dewar 96-05-18
-!keywords Size
-!reference 96-5564.a Robert Dewar 96-5-18>>
-!discussion
-
-Ken Garlington suggests
-
-  "For example, if an architecture had two "special" representations for
-   floating point (e.g., normal and extended floating point on a
-   MIL-STD-1750), a sufficiently large Size for a normal floating point
-   would cause the compiler to generate an extended floating point
-   representation. If there was only one representation for floating point,
-   then Size would have no effect. This also seems consistent with the
-   "minimal size" rule, in that a special representation for a number would
-   force the allocation of a certain number of bits regardless of Size."
-
-This seems very wrong. Remember that Size is a subtype specific attribute
-which means that you can get implicit conversions. Consider:
-
-    type x is float digits 5; -- 32 bits by default
-
-    function Sqrt (m : x) return x;
-
-    type y is new x;
-    for y'size use 64;
-
-according to Ken's suggestion, y would be represented in double precision,
-but when you called Sqrt you would get implicit narrowing to 32 bits. This
-seems very undesirable.
-
-The whole point is that Size should not make any significant changes to
-the internal representation. The idea of having Size affect the precision
-is not at all in the spirit of the RM requirements, and would be actively
-undesirable (though not non-conformant, just undesirable). I think it would
-be helpful if the AI makes clear that this is undesirable and explains why.
-
-Similarly Size on a fixed-point type can affect the padding, but should
-NOT affect the Small value.
-
-
-****************************************************************
-
-!section 13.3(42)
-!subject Comments to AIs regarding 'Size
-!reference AI95-00051
-!reference AI95-00109
-!reference 96-5552.a Ken Garlington  96-5-13
-!keywords Size
-!reference 96-5564.a Robert Dewar 96-5-18
-!from Randy Brukardt
-!reference 96-5569.a Ian Goldberg  96-5-22>>
-!discussion
-
-(From Randy Brukardt, although the header my say something different.)
-
->Ken Garlington suggests
->
->  "For example, if an architecture had two "special" representations for
->   floating point (e.g., normal and extended floating point on a
->   MIL-STD-1750), a sufficiently large Size for a normal floating point
->   would cause the compiler to generate an extended floating point
->   representation. If there was only one representation for floating point,
->   then Size would have no effect. This also seems consistent with the
->   "minimal size" rule, in that a special representation for a number would
->   force the allocation of a certain number of bits regardless of Size."
->
->This seems very wrong. Remember that Size is a subtype specific attribute
->which means that you can get implicit conversions. Consider:
->
->    type x is float digits 5; -- 32 bits by default
->
->    function Sqrt (m : x) return x;
->
->    type y is new x;
->    for y'size use 64;
->
->according to Ken's suggestion, y would be represented in double precision,
->but when you called Sqrt you would get implicit narrowing to 32 bits. This
->seems very undesirable.
->
->The whole point is that Size should not make any significant changes to
->the internal representation. The idea of having Size affect the precision
->is not at all in the spirit of the RM requirements, and would be actively
->undesirable (though not non-conformant, just undesirable). I think it would
->be helpful if the AI makes clear that this is undesirable and explains why.
-
-Well, I completely disagree about the 'undesirable' part.
-
-Our (read my) intent for our compiler was always that it would do this.
-I don't think we ever did it for floating point types, but we do allow it for
-all other types.  (Yes, our compiler [used to] allow explicitly changing
-the 'Small value for fixed point types; I think we took it out when some
-ACVC test pointed out it was illegal.  I know our compiler has code to
-do the needed conversions when parameter passing.)
-
-While changing representations on derived floating types might be
-unnecessary, it is very useful to allow this capability on first named
-subtypes.  Otherwise, there is no (semi) portable way to select a
-particular representation (for interfacing, for example):
-
-        Type My_Flt is Digits 5;
-        For My_Flt'Size Use 64;
-
-The only alternative ways is to select more precision than the program
-needs, or to add some sort of junk range which may not have anything
-to do with the program requirements.
-
-As with any programming, there is a certain amount of user-beware
-needed.  If someone specifies something unlikely that loses precision,
-that's their problem and just too bad.  (I don't find derived subprograms
-on a floating point type particularly likely, and the combination is even
-less likely.)
-
-We had to do something similar to be able to convert between the two
-representations of pointers on the Unisys 2200.
-
-        Type My_Ada_Ptr Is Access <something>;
-        Pragma Convention (My_Ada_Ptr, Ada);
-
-        Type My_C_Ptr Is New My_Ada_Ptr;
-        Pragma Convention (My_C_Ptr, C);
-
-An alternative way to specify that would have been:
-
-        Type My_Ada_Ptr Is Access <something>;
-        For My_Ada_Ptr'Size Use 36;
-
-        Type My_C_Ptr Is New My_Ada_Ptr;
-        For My_C_Ptr'Size Use 72;
-
-(I didn't do that because it was a lot more work to implement properly.)
-
-
-
-
-
-
-
-
-
-****************************************************************
-
-!section 13.3(42)
-!subject Comments to AIs regarding 'Size
-!reference AI95-00051
-!reference AI95-00109
-!reference 96-5552.a Ken Garlington  96-5-13
-!keywords Size
-!reference 96-5564.a Robert Dewar 96-5-18
-!from Robert Dewar
-!reference 96-5570.a Robert Dewar 96-5-22>>
-!discussion
-
-Randy said, replying to me
-
->>The whole point is that Size should not make any significant changes to
->>the internal representation. The idea of having Size affect the precision
->>is not at all in the spirit of the RM requirements, and would be actively
->>undesirable (though not non-conformant, just undesirable). I think it would
->>be helpful if the AI makes clear that this is undesirable and explains why.
-
->Well, I completely disagree about the 'undesirable' part.
->
->Our (read my) intent for our compiler was always that it would do this.
->I don't think we ever did it for floating point types, but we do allow it for
- all other types.  (Yes, our compiler [used to] allow explicitly changing
->the 'Small value for fixed point types; I think we took it out when some
->ACVC test pointed out it was illegal.  I know our compiler has code to
->do the needed conversions when parameter passing.)
-
-As best I understand it, this is a comment from Randy on how he would like
-the language to be, but it seems clear that this is not what is intended.
-The advice that Size not alter the internal representation of an item is
-clearly applicable in this case. Also the strong difference in rules between
-Size and Small indicates that the notion that Size could affect Small is
-not at all what is intended.
-
-Consider the following
-
-     type x is digits 5;
-
-     procedure Noop (a : in out x) is
-     begin
-        null;
-     end;
-
-     type y is new x;
-     for y'size use 64;
-
-It seems quite wrong that a call to Noop with an argument of type y would
-modify the value of the argument (by stripping extra precision). This is
-precisely why a 'Small attribute clause would not have been allowed for y
-in the corresponding fixed-point case, and it seems clear that Size is
-only expected to affect padding etc where the conversions do not have
-significant change-of-representation semantics. The whole idea of change
-of representation in Ada is that it should be explicit, never implicit.
-
-Randy, are you simply saying you don't think the language should have been
-designed with this restriction, or are you seriously suggesting that it is
-appopriate that 'Size clauses cause a change of representation resulting
-in implicit (non-trivial) change of representation conversions.
-
-
-****************************************************************
-
-!section 13.3(42)
-!subject Comments to AIs regarding 'Size
-!reference AI95-00051
-!reference AI95-00109
-!reference 96-5552.a Ken Garlington  96-5-13
-!keywords Size
-!reference 96-5564.a Robert Dewar 96-5-18
-!reference 96-5570.a Robert Dewar 96-5-22
-!from Randy Brukardt
-!reference 96-5571.a Ian Goldberg  96-5-23>>
-!discussion
-
-Robert gives the following example in replying to me (Randy Brukardt):
-
->Consider the following
->
->     type x is digits 5;
->
->     procedure Noop (a : in out x) is
->     begin
->        null;
->     end;
->
->     type y is new x;
->     for y'size use 64;
->
->It seems quite wrong that a call to Noop with an argument of type y would
->modify the value of the argument (by stripping extra precision). This is
->precisely why a 'Small attribute clause would not have been allowed for y
->in the corresponding fixed-point case, and it seems clear that Size is
->only expected to affect padding etc where the conversions do not have
->significant change-of-representation semantics. The whole idea of change
->of representation in Ada is that it should be explicit, never implicit.
-
-I of course agree that change of representation should be explicit,
-never implicit.  But the problem here is (taking some license) that
-programmer here is planning on using the EXPLICIT conversion to
-or from Y(...) to handle the conversion.  They just forgot that the
-Noop routine would be derived.
-
-Normal Ada programmers probably ought to avoid derived routines (for
-untagged types) altogether, because the rules are just too complex
-for the average programmer to understand.  It took us months to
-get this stuff right in our Ada 83 compiler, and I doubt we still have
-it right in our Ada 95 compiler.
-
-Anyway, explicit representation change via derived types has a long
-history in Ada, including an entire section devoted to the idea.  It seems
-very odd to deny a programmer (and implementors) the capability to
-specify a representation for floating point and fixed point types, but to
-allow it for all other types.  (It is true that the numeric conversion rules
-are liberal enough that it is not necessary to do this, which is probably
-why it was omitted in the first place.  But it is very natural, given that
-it must be done for access, array, and record types.)
-
-In any case, the most useful usage of 'Size to force a representation
-is on the first-named subtype of an original type declaration.  That
-is a capability which is not present anywhere else in the language,
-and one that is needed from time to time.  I think the original
-commentor had that case in mind, and that is mainly what I care
-about here.  The problem is that it is difficult to separate the
-cases.
-
-Some other way to specify a hardware floating-point representation
-would also fill the need, of course.  Pragma Float_Rep does not
-seem too satisfying, however, since such a usage could not be
-portable to another compiler.
-
-Ada 83 generally restricted clauses on derived types to those
-without primitive operations.  Such a restriction on representation
-changing clauses of any kind could be recommended, and
-eliminate Robert's concern, without throwing the baby out with
-the bathwater.
-
-(Of course, the fact that 'Size is a "subtype" attribute makes
-reasoning about it much more complex.  Once the capability
-to specify 'Size for subtypes was removed, there was no
-reason to retain "subtype" attributes [other than that they
-slightly simplify the description of 'Component_Size and
-record component clauses].  Unfortunately, such a change
-is too much for the ARG to undertake.)
-
-
-
-
-
-
-
-
-
-****************************************************************
-
-!section 13.3(42)
-!subject Comments to AIs regarding 'Size
-!reference AI95-00051
-!reference AI95-00109
-!reference 96-5552.a Ken Garlington  96-5-13
-!keywords Size
-!reference 96-5564.a Robert Dewar 96-5-18
-!reference 96-5570.a Robert Dewar 96-5-22
-!from Robert Dewar
-!reference 96-5572.a Robert Dewar 96-5-23>>
-!discussion
-
-Randy said
-
- (Of course, the fact that 'Size is a "subtype" attribute makes
- reasoning about it much more complex.  Once the capability
- to specify 'Size for subtypes was removed, there was no
- reason to retain "subtype" attributes [other than that they
- slightly simplify the description of 'Component_Size and
- record component clauses].  Unfortunately, such a change
- is too much for the ARG to undertake.)
-
-I don't find the reasoning complex. It is an invention of Ada 83, not
-Ada 95 that draws a strong distinction between size and other rep clauses
-such as record and enumeration representation clauses. The reason is the
-same in Ada 83 and Ada 95, namely that it is assumed that different sizes
-do NOT correspond to a significant change in repressenation.
-
-To make Size a type specific attribute in Ada 95 would introduce terrible
-upwards incompatibilities (the program I gave with Noop is legal Ada 83,
-and legal Ada 95, but would of course be illegal Ada 95 if we followed
-Randy's suggestion and made Size a type-related attribute).
-
-The fact of the matter is that Randy is complaining about a design decision
-made in Ada 83, which is unchanged in Ada 95. His recommendation of not using
-derived types for non-tagged types strikes me as absurd, since this is a much
-used feature in both Ada 83 and Ada 95 programs, in particular to effect
-change of representation. It sounds like the RR compiler at first missed
-the very important distinction between Size and other rep clauses, but this
-is a crucial distinction in Ada 83 as well as in Ada 95.
-
-It is quite in order to complain about this design decision, but that does
-not translate into action at this stage. I happen to think that the Ada 83
-decision (and the corresponding identical Ada 95 semantics) is quite
-reasonable, but in any case it is clearly the rule of the language as it
-stands, and I do not see any cogent argument for suggesting a change at
-this stage.
-
-
-****************************************************************
-
-!section 13.3(42)
-!subject Comments to AIs regarding 'Size
-!reference AI95-00051
-!reference AI95-00109
-!reference 96-5552.a Ken Garlington  96-5-13
-!keywords Size
-!reference 96-5564.a Robert Dewar 96-5-18
-!reference 96-5570.a Robert Dewar 96-5-22
-!reference 96-5571.a Ian Goldberg  96-5-23
-!from Erhard Ploedereder
-!reference 96-5573.a Erhard Ploedereder  96-5-24>>
-
-> Anyway, explicit representation change via derived types has a long
-> history in Ada, including an entire section devoted to the idea.  It seems
-> very odd to deny a programmer (and implementors) the capability to specify a
-> representation for floating point and fixed point types, but to allow it for
-> all other types.  (It is true that the numeric conversion rules are liberal
-> enough that it is not necessary to do this, which is probably why it was
-> omitted in the first place.  But it is very natural, given that it must be
-> done for access, array, and record types.)
-
-This argument conveniently ignores that this RM Section (13.6) in Ada9X
-talks only about records (and arrays) and requires the absence of inherited
-subprograms for derived records with rep.clauses. On might infer from the
-omission that such representation change for real types was considered
-undesirable.
-
-Note also RM 13.1(10) which imposes the "no-inherited subprograms" rule for
-all type-related rep.clauses (anything other than Size and Alignment) on
-derived types. It would be most curious if
-  for T'Small use ...   were illegal, while
-  for T'Size use        were legal with an effect that changes 'Small.
-
-
-
-
-
-
-
-****************************************************************

Questions? Ask the ACAA Technical Agent