CVS difference for ais/ai-00051.txt

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

--- ais/ai-00051.txt	1999/11/29 21:14:21	1.4
+++ ais/ai-00051.txt	2004/04/30 02:35:36	1.5
@@ -1,4 +1,4 @@
-!standard 13.03    (42)                               99-11-29  AI95-00051/10
+!standard 13.03    (42)                               04-04-08  AI95-00051/11
 !class binding interpretation 95-06-25
 !status work item 98-04-01
 !status ARG Approved (subject to letter ballot)  8-0-2  97-11-14
@@ -7,425 +7,3416 @@
 !status work item (letter ballot was 8-2-1) 96-06-05
 !status ARG approved (subject to letter ballot) ???  95-11-01
 !status received 95-06-25
-!reference AI95-00109
+!reference AI95-00291
 !priority High
 !difficulty Medium
-!subject Size and Alignment Clauses for Objects
+!subject Size and Alignment clauses
+
+!summary
+
+This AI describes the recommended level of support for Size and Alignment
+clauses for subtypes and for objects.
+
+This AI combines the previous AI-109 (treating subtypes and objects in separate
+AIs turned out to be a bad idea), but removes discussion of aliased objects
+(now treated in AI-291).
+
+The following Recommended Level of Support is added:
+
+1. The implementation should support a Size or Alignment clause for an
+   object if it specifies the same Size or Alignment that the
+   implementation would have chosen by default (i.e. a "confirming"
+   representation clause, as defined in AI 291).
+
+2. For a signed integer type, the implementation need not support a
+   Size/Alignment clause which specifies a value larger than the largest
+   Size/Alignment value that would be chosen by the implementation by default
+   (i.e. in the absence of a representation clause) for any signed integer
+   type. Similarly for modular integer types, fixed point types, enumeration
+   types, record types, and array types.
+
+3. Only confirming Size/Alignment clauses need be supported for floating point
+   types, access types, protected types, and task types.
+
+4. Non-power-of-two alignments need not be supported.
+
+5. Confirming representation clauses have no semantic effect (this means
+   eliminating rules of the form "If attribute Xyz is specified, then" ...)
+
+!question
+
+What is the recommended level of support for Size and Alignment clauses?
+
+For example, the recommended level of support for the Size attribute
+of an object (in RM-13.3(42,43)) implies that the following should be
+accepted:
+
+    X: Integer;
+    for X'Size use 1024;
+
+Is this the intent? (No).
+
+!recommendation
+
+(See summary.)
+
+!wording
+
+In 13.3(25) replace:
+    "If the Alignment of a subtype is specified, then the Alignment of an object is
+     at least as strict, unless the object's Alignment is also specified".
+with
+    "The Alignment of an object is as at least as strict as the alignment
+     of its subtype, unless the object's Alignment is specified".
+
+Replace 13.3(28) with
+    "Program execution is erroneous if an object that is not allocated under
+     control of the implementation is not aligned according to its Alignment".
+
+Replace 13.3(30-32) with:
+
+    - An implementation need not support a nonconfirming Alignment clause
+      specifying an Alignment which is neither zero nor a power
+      of two.
+
+    - An implementation need not support an Alignment clause for a signed
+      integer type specifying an Alignment greater than the largest Alignment
+      value that would be chosen by default (i.e. in the absence of an
+      Alignment clause) for any signed integer type. Similarly for
+      modular integer types, fixed point types, enumeration types, record
+      types, and array types.
+
+    - For floating point types, access types, protected types, and task types,
+      an implementation need not support a nonconfirming Alignment clause.
+
+    - An implementation need not support a nonconfirming Alignment clause
+      which cannot be implemented efficiently using the available machine
+      instructions.
+
+Replace 13.3(42-3) with
+    The recommended level of support for the Size attribute of objects is
+    the same as for subtypes (see below).
+
+In 13.3(50) replace
+    "If the Size of a subtype is specified, and allows for independent ..."
+with
+    "If the Size of a subtype allows for independent ..."
+.
+
+Insert after 13.3(56) (as part of the bulleted list)
+
+    - An implementation need not support a Size clause for a signed
+      integer type specifying a Size greater than the largest Size
+      value that would be chosen by default (i.e. in the absence of an
+      Size clause) for any signed integer type. Similarly for
+      modular integer types, fixed point types, and enumeration types,
+      record types, and array types.
+
+    - For floating point types, access types, protected types, and task types,
+      an implementation need not support a nonconfirming Size clause.
+
+!discussion
+
+This AI depends on AI 291's definition of "confirming", as well as AI 291's
+coverage of various cases involving aliased objects and by-reference types.
+
+Are the sentences beginning with "Similarly for" in 13.3(30-32) and 13.3(56)
+ok, or would something like "Similar advice applies for" be better?
+
+This AI does not address questions about the meaning of the Size attribute
+(e.g. the Size attribute of an unconstrained object of a discriminated type).
+Is there any need to explicitly state that this is implementation dependent?
+
+Is it ok to require support for nonconfirming Size and Alignment clauses
+for fixed point subtypes and objects?
+
+!example
+
+This example shows some ramifications of the Recommended Level of Support.
+For each representation clause, we note whether it is covered by the
+Recommended Level of Support [Should be supported], whether it might be
+covered by the Recommended Level of Support (depending on the largest
+values allowed for integers) [Might be supported], or is not covered
+by the Recommended Level of Support [Need not be supported].
+
+    type Unspecified is range System.Min_Int .. System.Max_Int;
+        -- no Size or Alignment clause
+
+    type T1 is range 1 .. 10;
+    for T1'Size use Unspecified'Size; -- Should be supported
+    for T1'Alignment use Unspecified'Alignment; -- Should be supported
+
+    type T2 is range 1 .. 10;
+    for T2'Size use 2 * Unspecified'Size; -- Might be supported
+
+    type T3 is range 1 .. 10;
+    for T3'Size use 2 * Unspecified'Alignment; -- Might be supported
+
+    type T4 is new Integer;
+    for T4'Alignment use 3;  -- Need not be supported
+
+!appendix
+
+!section 13.3(42)
+!subject Object'Size
+!reference RM95-13.3(42,43)
+!from Keith Thompson 95-05-10
+!reference as: 95-5141.a Keith Thompson 95-5-10>>
+!discussion
+
+The recommended level of support for the Size attribute of an
+object implies that the following should be accepted:
+
+    X: Integer;
+    for X'Size use 1024;
+
+Is this the intent?  If so, what should be done with the extra 922 bits
+(if Integer'Size = 32)?  If X is passed as a parameter, must all 1024 bits
+be copied?  (Presumably not, since the callee won't be expecting them.)
+
+A possible implementation is to treat only the first 32 of the 1024 bits
+as an Integer object, but then the other 922 bits are effectively not
+part of X.  It seems more sensible to reject the size clause.  I see
+little point in allowing a 'Size for an integer object to exceed the
+largest size of any integer type.
+
+Suggestion: for elementary types, the recommended level of support for
+the Size attribute should not call for sizes larger than the largest
+supported size for the class (discrete, float, access, etc.).
+
+****************************************************************
+
+!section 13.3(42)
+!subject Size clauses for objects specifying large sizes
+!reference AI95-00051
+!reference 13.3(42)
+!from Tucker Taft 95-10-30
+!reference 95-5373.g Tucker Taft 95-10-30>>
+!discussion
+
+This AI talks about base subtypes, which don't exist for
+non-scalar types.  In general, when you start talking about
+representation items, I find it is better to consider "integral" scalar types
+(integer, enum, and fixed), floating point types, access types, array types,
+and non-array composite types separately, rather than grouping everything
+together.  If the right answer happens to be the same for each of
+these distinct groups, great.  But don't be afraid to admit that
+different rules are needed for different kinds of types.
+
+As far as this AI, I think its recommendations are reasonable for
+"integral" scalar subtypes.
+
+For floating point and access subtypes, I don't think the implementation
+needs to accept anything but a "confirming" Size clause.
+
+For composite types, the Size clause on an object presumably just
+specifies some amount of padding on allocation, but has no effect on any
+other operations on the type, and hence is pretty trivial to support.
+Even "block assignment" of a "padded" composite object should not
+be affected, since assignment is really defined more in terms of
+component-wise assignment, and clearly there are no additional components.
+In particular, any gaps in the middle of a composite type don't need
+to be assigned, compared, or whatever, as part of a predefined operation on
+a composite object.  So clearly padding at the end can be ignored
+for these operations as well.
+
+Hence, for composite types, I would suggest that any size that is
+a multiple of the storage unit, and is at least as big as the subtype
+'Size, be accepted.  It need have no effect other than to add padding
+at the end of the object.
+
+****************************************************************
+
+!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
+-- many folks think that you 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
+-- what did your Ada 83 implementations 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:
 
-!summary
+> 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.
 
-This AI addresses the requirements for which Size and Alignment clauses
-must be supported for objects.  For Size and Alignment of subtypes, see
-AI95-00109.  This AI also addresses various representation items when
-applied to aliased objects.
+Sorry for the confusion.
 
-The following Recommended Level of Support is added:
+- Bob
 
-1. The implementation should support a Size or Alignment clause for an
-object if it specifies the same Size or Alignment that the
-implementation would have chosen by default.
+****************************************************************
 
-2. For an aliased object, the implementation need not support a
-representation clause that causes the object to have a Size or Alignment
-that is different from what the implementation would have chosen by
-default.  (For aliased stand-alone objects, this applies to Size and
-Alignment clauses.  For aliased record or record extension components,
-this applies to component_clauses.  For aliased array components, this
-applies to Component_Size clauses.)  For a pragma Pack, the
-implementation need not pack an aliased component in such a way that
-gives it a different Size or Alignment than it would have without the
-pragma Pack.
-
-3. For a non-aliased object, the implementation should support a Size
-clause specifying a Size up to (at least) the following values, which
-depends on the class of the object.  (Similarly, the implementation
-should support a Component_Size clause and a
-record_representation_clause specifying the Size of a component up to
-(at least) these values, depending on the class of the component.)
-
-    - For a signed integer, up to the Size of the largest signed integer
-      type supported by the implementation.
-
-    - For a modular integer, up to the Size of the largest modular
-      type supported by the implementation.
-
-    - For an object of an enumerated type, up to the Size of the largest
-      signed integer type, or the largest modular type, whichever is
-      smaller.
-
-For fixed point, floating point, access, and composite objects, the
-implementation need not support any Size other than what would be chosen
-by default.
-
-In the discrete case, any extra bits are set to appropriate values when
-assigning to the object whose Size has been specified; for example, the
-value being assigned should be zero-extended or sign-extended as
-appropriate.  When reading from the object, any extra bits may be
-ignored.
-
-In the composite case, any extra bits may be ignored, and may be left
-undefined.
-
-4. For a non-aliased object, the implementation need not support an
-Alignment clause unless:
-
-    - For a signed integer, the Alignment is less than or equal to that of
-      the largest signed integer type supported by the implementation.
-
-    - For a modular integer, the Alignment is less than or equal to that of
-      the largest modular type supported by the implementation.
-
-    - For an object of an enumerated type, 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, and composite objects, the
-implementation need not support any Alignment other than what would be
-chosen by default.
-
-In addition, the following Implementation Advice (not Recommended Level
-of Support) is added:
-
-For Mutable_Obj'Size, where Mutable_Obj denotes a view of an object
-whose type has discriminants with defaults: If the view is
-unconstrained, the Size should reflect the total size allocated for the
-object.  If the view is constrained, the Size should reflect the current
-size of the object, given its current discriminant values.
+!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
 
-!question
+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.
 
-First question: The recommended level of support for the Size attribute
-of an object (in RM-13.3(42,43)) implies that the following should be
-accepted:
+- Bob
 
-    X: Integer;
-    for X'Size use 1024;
+****************************************************************
 
-Is this the intent?  If so, what should be done with the extra 922 bits
-(if Integer'Size = 32)?  If X is passed as a parameter, must all 1024 bits
-be copied?  (Presumably not, since the callee won't be expecting them.)
+!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
 
-Second question: What is the meaning of the Size attribute for an
-unconstrained variable that is of a mutable type?  Consider:
+> 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.
 
-    subtype Small_Natural is Natural range 0..100;
-    type Mutable(Len: Small_Natural := 0) is
+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;
+-- This is a main program that calls the Ada 83 parts of the Size test.
+-- See also Size_Test_95.
+
+-- All the work is done during 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;
+-- This is a main program that calls the Ada 83 *and* Ada 95 parts
+-- of the Size test.
+-- See also Size_Test_83.
+
+-- All the work is done during 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
-            Chars: String(1..Len);
+            In_Ready: Boolean;
+            Out_Ready: Boolean;
         end record;
-    X: Mutable;
+    pragma Pack(Device_Info); -- Device_Info'Size = 2.
 
-Suppose the implementation allocates the maximum possible size for X
-(perhaps 104 bytes).  The "current size" of the value of X (i.e. the
-"constrained size", with Len constrained to 0) is perhaps just 4 bytes
-(for Len -- the Chars field is empty).  Should X'Size be the current
-size (perhaps 4*8) or the maximum size (perhaps 104*8)?  The RM does not
-answer this question.
+    type Device_Array is Array (1..4) of Device_Info;
+    for Device_Array'Component_Size use 2;
 
-!recommendation
+    Dev : Device_Array;
 
-(See summary.)
+    procedure Operate (A : In Out Device_Info);
 
-!wording
+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.
 
-To Be Determined.
+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
 
-First question:
+>> 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.
 
-Clearly, an implementation ought to support "confirming" Size and
-Alignment clauses, and there is little burden in doing so.
+Thus, most of the examples we have been discussing are relavant only in =
+terms of permitted support, as opposed to required support.
 
-The restrictions on Size and Alignment clauses for aliased objects are
-necessary, because one can form a pointer to an aliased object (either
-an access value, or a value of type Address).  Dereferences through the
-pointer will not know about any Size or Alignment clause on the object.
-For example, suppose Integer'Size = 32:
-
-    type Int_Ptr is access all Integer;
-    X: aliased Integer;
-    for X'Size use 64;
-    Y: Int_Ptr := X'Access;
-
-Now, depending on where the extra bits are allocated, a dereference of Y
-might get the "wrong" 32 bits.
-
-The same reasoning applies to component_clauses and Component_Size
-clauses, since these can affect the Size and Alignment of the
-components.
-
-The same reasoning applies to pragma Pack, except that instead of
-refusing to support the pragma, the implementation should avoid packing
-the aliased component(s) too tightly.
-
-Note that on some machines, it may be feasible to support some Size or
-Alignment clauses that are not required by point (2) of the Summary.
-Thus, point (2) says "need not" (as opposed to "should not" or "must
-not").  For example, on some machines, alignment primarily affects the
-speed of the machine code, rather than its correctness.
-
-As to the restrictions on Size clauses for non-aliased objects, it seems
-unreasonable to require arbitrarily large values for discrete types.
-Values up to the maximum supported for the class make sense, since the
-implementation already knows how to do sign extension or zero extension,
-as appropriate, for type conversions.  The extra bits should not be left
-undefined, because if one takes the Address of such an object, one
-expects to have well-defined data in all of its bits.  The
-representation of fixed point, floating point, and access types is often
-special, so we place no requirements other than to support "confirming"
-Size clauses.  For composite objects, it might be an implementation
-burden to require arbitrarily large Sizes.  For example, one
-implementation reportedly implements small packed arrays of Booleans in
-the same manner as modular types.  If arbitrarily large Sizes for
-modular types are not supported, then arbitrarily large Sizes for such
-packed arrays can't be supported, either, given this (reasonable)
-implementation strategy.
-
-Relevant wording from the RM follows:
-
-13.3 says:
-
- 42   {recommended level of support [Size attribute]} The recommended level of
- support for the Size attribute of objects is:
-
-    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).
-
- ...
-
- 54   {recommended level of support [Size attribute]} 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.
-
-These recommendations are hard requirements for implementations that
-support the Systems Programming Annex, by C.2(2):
-
- 2   {recommended level of support [required in Systems Programming Annex]}
- The implementation shall support at least the functionality defined by the
- recommended levels of support in Section 13.
-
-13.1(7) says:
-
- 7   {representation of an object} {size (of an object)} The representation of
- an object consists of a certain number of bits (the size of the object).
- These are the bits that are normally read or updated by the machine code when
- loading, storing, or operating-on the value of the object.  This includes
- some padding bits, when the size of the object is greater than the size of
- its subtype.  {gaps} {padding bits} Such padding bits are considered to be
- part of the representation of the object, rather than being gaps between
- objects, if these bits are normally read and updated.
-
-It is not clear what "bits that are normally read or updated" means for
-composite types, since assignment and comparison are defined in terms of
-individual components.  For example, on an assignment, there is no
-requirement that gaps in the middle of the object be copied, so clearly
-there should be no such requirement on extra bits added to the end of
-the object.  For scalars, however, all bits in the representation of the
-object should be set to some meaningful value.
-
-
-Similar reasoning applies to Alignment clauses for non-aliased objects.
-It seems unreasonable to require arbitrary values for discrete types. Values
-already supported for the class make sense, since the implementation already
-knows how to do such alignments. But requiring additional alignments simply
-add to the implementation burden. There may be hardware requirements on the
-alignment of an integer. For instance, some machines require 32-bit integers
-to be 32-bit aligned. An implementation for such hardware should not be
-required to support 8-bit aligned 32-bit integers. (* Oops: The rules as
-written require mis-aligned integers. Is this a bug?? *) Similarly, 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. For composite objects, it might be an implementation burden
-to require arbitrary alignments (even within those required by the language),
-as there may be stricter requirements on the component subtypes or on the
-type as a whole. Again, consider the example of implementing small packed
-arrays of Booleans in the same manner as modular types. If there exist
-Alignments for modular types that are not supported, then these Alignments
-can't be supported for such packed arrays.
-
-Relevant wording from the RM follows:
-
-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.
-
-33   The recommended level of support for the Alignment attribute for objects
-is:
-
-   34  Same as above, for subtypes, but in addition:
-
-   35  For stand-alone library-level objects of statically constrained
-       subtypes, the implementation should support all Alignments
-       supported by the target linker.  For example, page alignment is
-       likely to be supported for such objects, but not for subtypes.
-
-These recommendations are hard requirements for implementations that
-support the Systems Programming Annex, by C.2(2) (see above)
-
-These requirements are both vague, and possibly require implementations to
-support non-natural alignments. The vague requirements cannot be depended on
-by users. They are replaced by this AI (for objects) and by AI-00109 (for
-subtypes).
+****************************************************************
 
+!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.
 
-Second question: In the example, X'Size should be the max size.  Here's
-why: Suppose we add a Size clause to the above:
+Yes.  The question is: should more support be required and/or
+recommended?
 
-    for X'Size use 104*8; -- Specify the Size of the *object*.
+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).
 
-Clearly, this will not be legal if 104*8 is less than the max possible
-size.  By 13.1(17), a query of X'Size *must* now return 104*8.
-13.1(17.a) gives an example of this.  So, in the case of a specified
-Size (on the object), the query *cannot* return the current size.
+- Bob
 
-To preserve the principle that confirming rep clauses shouldn't change
-things, we must use the same rule even when there's *not* a Size clause.
+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".
 
-Now, suppose we have a constrained object:
+****************************************************************
 
-    subtype Mutable_3 is Mutable(Len => 3);
-    Y: Mutable_3;
-    Z: constant Mutable := (Len => 3, Chars => "abc");
+!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
 
-Here, the compiler will not allocate the max size.  Y'Size and Z'Size
-should clearly be the *constrained* Size -- the Size given that Len = 3.
+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...)
 
-Now, suppose we have a parameter:
+AI95-00109/01:  I am strongly in favor of the Robert Dewar position
+described in the commentary, including his "Ulterior Motive".
 
-    procedure Proc(Param1: Mutable; -- Constant; therefore constrained.
-                   Param2: in out Mutable3; -- Constrained.
-                   Param3: in out Mutable) is
-    begin
-        ...
-    end Proc;
 
-    Proc(X, X, X); -- Unconstrained actual parameters.
-    Proc(Y, Y, Y); -- Constrained actual parameters.
+****************************************************************
 
-Inside Proc, Param1'Size and Param2'Size should be the constrained size,
-based on the value of the actual parameter's discriminant.  The
-alternative would be to return the max size if the actual parameter
-denotes an unconstrained object.  But that's not really reasonable from
-an implementation point of view -- inside Proc, we don't know whether
-the actual denotes an unconstrained object.
+!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
 
-For Param3, however, we *do* know whether the actual is constrained or
-unconstrained -- it is necessary to pass extra dope to implement the
-'Constrained attribute.  Therefore, Param3'Size should be the max size,
-or the constrained size, depending on the constrainedness of the actual
-view.  (Note: we say "view" there because the actual could be another
-formal -- we should care about the constrainedness of the actual *view*,
-not the constrainedness of the actual *object*.)
+Ken Garlington suggests
 
-Note: all aliased objects are constrained, so the parameter issue does
-not come up for access values.  That is, Ptr.all'Size will clearly
-always return the constrained size.
+  "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.
 
-Now, what about implementations that don't allocate the max?  That is,
-implementations that use the deallocate/reallocate approach, when
-assigning to a mutable record?  Such an implementation would
-return the constrained size, even when the object is unconstrained.
+Similarly Size on a fixed-point type can affect the padding, but should
+NOT affect the Small value.
 
-The answer to these questions about mutable types should be
-Implementation Advice, since the exact semantics of Size is not defined
-by the language in these cases anyway.  A hard requirement is uncalled
-for in this case (even for the SP Annex).
 
-!appendix
+****************************************************************
 
 !section 13.3(42)
-!subject Object'Size
-!reference RM95-13.3(42,43)
-!from Keith Thompson 95-05-10
-!reference as: 95-5141.a Keith Thompson 95-5-10>>
+!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
 
-The recommended level of support for the Size attribute of an
-object implies that the following should be accepted:
+(From Randy Brukardt, although the header my say something different.)
 
-    X: Integer;
-    for X'Size use 1024;
+>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.
 
-Is this the intent?  If so, what should be done with the extra 922 bits
-(if Integer'Size = 32)?  If X is passed as a parameter, must all 1024 bits
-be copied?  (Presumably not, since the callee won't be expecting them.)
+Well, I completely disagree about the 'undesirable' part.
 
-A possible implementation is to treat only the first 32 of the 1024 bits
-as an Integer object, but then the other 922 bits are effectively not
-part of X.  It seems more sensible to reject the size clause.  I see
-little point in allowing a 'Size for an integer object to exceed the
-largest size of any integer type.
+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.)
 
-Suggestion: for elementary types, the recommended level of support for
-the Size attribute should not call for sizes larger than the largest
-supported size for the class (discrete, float, access, etc.).
+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 Size clauses for objects specifying large sizes
+!subject Comments to AIs regarding 'Size
 !reference AI95-00051
-!reference 13.3(42)
-!from Tucker Taft 95-10-30
-!reference 95-5373.g Tucker Taft 95-10-30>>
+!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
 
-This AI talks about base subtypes, which don't exist for
-non-scalar types.  In general, when you start talking about
-representation items, I find it is better to consider "integral" scalar types
-(integer, enum, and fixed), floating point types, access types, array types,
-and non-array composite types separately, rather than grouping everything
-together.  If the right answer happens to be the same for each of
-these distinct groups, great.  But don't be afraid to admit that
-different rules are needed for different kinds of types.
+Randy said, replying to me
 
-As far as this AI, I think its recommendations are reasonable for
-"integral" scalar subtypes.
+>>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.
 
-For floating point and access subtypes, I don't think the implementation
-needs to accept anything but a "confirming" Size clause.
+>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.
 
-For composite types, the Size clause on an object presumably just
-specifies some amount of padding on allocation, but has no effect on any
-other operations on the type, and hence is pretty trivial to support.
-Even "block assignment" of a "padded" composite object should not
-be affected, since assignment is really defined more in terms of
-component-wise assignment, and clearly there are no additional components.
-In particular, any gaps in the middle of a composite type don't need
-to be assigned, compared, or whatever, as part of a predefined operation on
-a composite object.  So clearly padding at the end can be ignored
-for these operations as well.
+****************************************************************
 
-Hence, for composite types, I would suggest that any size that is
-a multiple of the storage unit, and is at least as big as the subtype
-'Size, be accepted.  It need have no effect other than to add padding
-at the end of the object.
+!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.
+
 ****************************************************************
 
 !section 13.3(40)
@@ -966,6 +3957,65 @@
 
 I do not like the terminology of evenly divides. It is much clearer
 to say that x is an exact multiple of y.
+
+****************************************************************
+
+From: 	Gary Dismukes
+Sent: 	Thursday, April  8, 2004  1:12 PM
+
+[Editor's note: These problems were corrected in version /11 of the AI as
+filed.]
+
+In the !summary:
+
+> 2. For a signed integer type, the implementation not support a Size/Alignment
+
+I believe that should be: "... the implementation need not support ..."
+
+>    clause which specifies a value larger than the largest Size/Alignment value
+>    that would be chosen by the implementation by default (i.e. in the absence
+>    of a representation clause) for any signed integer type. Similarly
+>    for modular integer types, fixed point types, enumeration types, record
+>    types, and array types.
+
+In the !example section:
+
+>     type T2 is range 1 .. 10;
+>     for T2'Size use 2 * Unspecified'Size;
+>         -- support might not be recommended
+>
+>     type T3 is range 1 .. 10;
+>     for T3'Size use 2 * Unspecified'Alignment;
+>         -- support might not be recommended
+
+It seems odd to say "support might not be recommended" on T2 and T3.
+
+Seems like the phrasing should be simply "-- might not be supported",
+since this is a comment on implementations, and the RM wording doesn't
+require this support.
+
+****************************************************************
+
+From: 	Stephen W. Baird
+Sent: 	Thursday, April  8, 2004  10:35 PM
+
+...
+> I believe that should be: "... the implementation need not support ..."
+
+Right.
+
+> It seems odd to say "support might not be recommended" on T2 and T3.
+>
+> Seems like the phrasing should be simply "-- might not be supported",
+> since this is a comment on implementations, and the RM wording doesn't
+> require this support.
+
+I intended the comments in this section to refer to the recommended level of
+support (which is, after all, the topic of the AI) rather than to
+implementations, but I have no objection to changing the comment to "-- might
+not be supported" if this seems clearer.
+
+Thanks for the careful reading and the feedback.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent