CVS difference for ais/ai-00216.txt

Differences between 1.1 and version 1.2
Log of other versions for file ais/ai-00216.txt

--- ais/ai-00216.txt	1999/03/30 01:38:51	1.1
+++ ais/ai-00216.txt	1999/10/07 00:25:07	1.2
@@ -1,4 +1,4 @@
-!standard 03.08.01      (01)                        99-03-23  AI95-00216/01
+!standard 03.08.01      (01)                        99-09-30  AI95-00216/02
 !class amendment 99-03-23
 !status work item 99-03-23
 !status received 99-03-23
@@ -41,55 +41,62 @@
 have multiple discriminants, to support the possibly
 nested unions being selected along different dimensions.
 
-Normally the Ada type should have defaults for all discriminants.
-However, if the type is limited, defaults are not required.
+The Ada type must have defaults for all discriminants.
+All objects of the type, even if limited or allocated in the heap
+(and hence effectively constrained by the initial discriminant value(s)),
+should be allocated the size C would allocate for the corresponding
+struct/union, which will be at least the maximum size required for any
+discriminant value.  This is because any whole-object assignments performed
+to or from such an object by the C code will generally involve this maximum
+size, even if they preserve the (conceptual) discriminant value.
+[Note that requiring defaults is not really necessary, but it
+seems benign, and suggests to the reader that objects of such a type
+are always allocated the max size, and are generally "mutable."]
+
+Each discriminant of an object of an unchecked_union type
+must be specified (explicitly or implicitly) when the object is created,
+even though its value is not stored, to enable appropriate default
+initialization of the appropriate variant(s), or to determine which fields
+should appear in a record aggregate.
 
-If the type is non-limited, then all objects of the type, even
-if allocated in the heap (and hence normally considered constrained
-by the initial discriminant value), should be allocated the size
-C would allocate for the corresponding struct/union, which will
-be at least the maximum size required for any discriminant value.
-This is because any whole-object assignments performed to or from
-such an object by the C code will generally involve this maximum size,
-even if they preserve the (conceptual) discriminant value.
-
-If the type is limited, the "exact" size may be allocated, determined
-by the value of the discriminant specified when the object is created.
-It is erroneous for a whole-object assignment to be performed to or
-from an object of a limited unchecked_union type which is passed to C code,
-because it would generally read or write past the end of the object.
-
-A discriminant of an object of an unchecked_union type may not
-be read, except in a default initialization expression for
-a component.  The discriminant(s) must be specified (explicitly
-or implicitly) when an object of the type is created, even though
-its (their) value is not stored, to enable appropriate default initialization
-of the appropriate variant(s), or to determine which fields should
-appear in a record aggregate.
-
-Constrained subtypes of an unchecked_union type are permitted,
-as this may be necessary to properly specify the discriminant
-value for a variable of the type.  It is erroneous to perform
-any operation (in C or Ada) that would have failed a discriminant
-check had the discriminant been present at run-time.
-
 Within the definition of an unchecked_union type, the discriminant(s)
 may not be used in a constraint in a component_definition, unless
 the type of the component is itself an unchecked_union type.  This
 is to ensure that the size of the component does not depend on the
-value of the discriminant.
+value of the discriminant.  Note that the discriminant may be used
+to govern a discriminant part, or as a default initial value for
+a component.
 
-In an instantiation of a generic, if the actual type is an
-unchecked union, then the formal type must not have known
-discriminants, to avoid contract violations involving discriminant
-references in the body of the generic.
-
-To avoid generic contract violations, if the type is non-limited,
-both equality and assignment are permitted.  Both are defined
-in terms of block operations operating on all bits of the representation.
-A warning on uses of equality would be appropriate, given the possiblity
-of uninitialized gaps in the representation.
+Outside the definition of the object's type, a discriminant
+of an object of an unchecked_union type must not be read.
 
+Constrained subtypes of an unchecked_union type are permitted,
+as this may be necessary to properly specify the (initial) discriminant
+value for a variable or subcomponent having the type.  It is erroneous to
+perform any operation (in C or Ada) that would have failed a discriminant
+check had the discriminant been present at run-time.
+
+The pragma Unchecked_Union may be applied to a derived type,
+presuming its ultimate ancestor type meets the requirements for the pragma.
+Converting the derived type to an ancestor (checked) type raises
+Program_Error.  Converting from an ancestor (checked) type to the derived
+type is permitted, and simply drops the discriminant(s) (and performs
+whatever other representation adjustments are necessary).
+
+In an instantiation of a generic, so as to avoid contract violations involving
+discriminant references in the body of the generic, if the actual type is an
+unchecked union, then, if the formal type is private, it must not have known
+discriminants, or if the formal type is derived, the specified ancestor type
+must also be an unchecked union.
+
+To avoid other kinds of generic contract violations, if the type is
+non-limited, all of the normal operations of a non-limited type exist,
+including assignment, equality, membership, 'Read, 'Write, 'Input,
+'Output, etc.  Assignment is defined in terms of a block copy on all bits
+of the representation.  The other operations all raise Program_Error,
+because they generally require reading the value of the discriminant
+to give a meaningful result.
+
 !wording
 
 
@@ -160,22 +167,6 @@
 if such types are going to be used in relatively portable C interfacing
 code with compilers that may share generics.
 
-We have proposed a distinction in the handling of limited and non-limited
-unchecked_union types.  Basically, objects of a limited unchecked
-union type are presumed not to change their (conceptual) discriminant
-during their lifetime, whereas objects of a non-limited type can.
-Furthermore, block assignment to or from objects of a non-limited
-unchecked union type are expected to involve the "max size" for
-the type, whereas such block assignments are presumed not to occur
-for limited unchecked_union types.  This permits the more efficient
-use of storage by using limited unchecked_union types in cases where
-the size varies significantly between the different variants.  This
-corresponds to the case in C where the programmer uses extra effort
-to allocate only what space is needed for the particular element of
-the union being created, knowing that the object's "kind" (however
-that might be defined in C) does not change after the object is
-created.
-
 !appendix
 
 Randy Brukardt  99-03-29
@@ -185,3 +176,65 @@
 considered at that meeting.
 
 *************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Friday, October 1, 1999 at 2:09 AM
+
+Agreed, just a suggestion: [Editor's note, this a comment on version 2]
+
+> To avoid other kinds of generic contract violations, if the type is
+> non-limited, all of the normal operations of a non-limited type exist,
+> including assignment, equality, membership, 'Read, 'Write, 'Input,
+> 'Output, etc.  Assignment is defined in terms of a block copy on all bits
+> of the representation.  The other operations all raise Program_Error,
+> because they generally require reading the value of the discriminant
+> to give a meaningful result.
+>
+It seems to me that completely forbidding the use of  'Read and 'Write is
+too strict; there are certainly cases where you want to send such types over
+a network!
+'Read and 'Write could be defined like the case where there are no default
+values (i.e. no discriminants written).
+'input and 'output could raise Program_Error, or do the same.
+
+OTOH, it is always possible for the user to redefine 'read and 'write...
+Well, in that case, it is important to NOT define 'input and 'output as
+raising P_E, since their normal behaviour (for discriminated defaulted
+types) is simply to call 'Read and 'Write.
+
+*************************************************************
+
+From: Robert A Duff
+Sent: Friday, October 1, 1999 at 8:57 am.
+
+> It seems to me that completely forbidding the use of  'Read and 'Write is
+> too strict; there are certainly cases where you want to send such types over
+> a network!
+> 'Read and 'Write could be defined like the case where there are no default
+> values (i.e. no discriminants written).
+> 'input and 'output could raise Program_Error, or do the same.
+>
+> OTOH, it is allways possible for the user to redefine 'read and 'write...
+
+As Tucker mentioned in the meeting, another way to get the operations
+that raise Program_Error is to first define the variant record as a
+normal type, then derive from it, and declare the derived type to be an
+unchecked_union.  Then you can convert values to the parent type, and do
+all the normal stuff without getting Program_Error.
+
+Oh, and by the way, we decided that you could convert to constrained
+subtypes of the parent type (contrary to what Tuck's write-up says).
+Of course you can't convert to an unconstrained subtype, because the
+compiler can't know what the discriminant value should be.
+
+> Well, in that case, it is important to NOT define 'input and 'output as
+> raising P_E, since their normal behaviour (for discriminated defaulted
+> types) is simply to call 'Read and 'Write.
+
+Good point.
+
+- Bob
+
+*************************************************************
+
+

Questions? Ask the ACAA Technical Agent