CVS difference for ais/ai-00108.txt

Differences between 1.7 and version 1.8
Log of other versions for file ais/ai-00108.txt

--- ais/ai-00108.txt	2000/04/20 20:20:13	1.7
+++ ais/ai-00108.txt	2000/06/02 00:23:26	1.8
@@ -1,4 +1,4 @@
-!standard 13.13.02 (09)                               00-03-07  AI95-00108/05
+!standard 13.13.02 (09)                               00-06-01  AI95-00108/06
 !standard 13.13.02 (27)
 !standard 13.13.02 (36)
 !class binding interpretation 96-04-04
@@ -21,6 +21,9 @@
 
 The Input and Output attributes are not inherited by a type extension.
 
+Default stream attributes are never inherited; rather, the default
+implementation for the derived type is used.
+
 The stream attributes must work properly for every language defined
 nonlimited type.  For language defined private types, the output
 generated by the Write attribute is not specified, but it must be
@@ -44,6 +47,16 @@
 Do these rules apply to the stream-oriented attributes Read, Write,
 Input, and Output?  (No.)
 
+If an untagged derived type includes a known discriminant part, the number of
+discriminants can change. If we inherit the parent's attribute definition, we
+could write the wrong number of discriminants. Consider:
+
+        type Parent (D1, D2 : Integer := 1) is ...;
+        type Child (D : Integer := 2) is new Parent (D1 => D, D2 => D);
+
+Clearly the default implementation of Parent'Write writes two discriminant
+values.  How many discriminants does Child'Write write? (One.)
+
 Are the stream-oriented attributes intended to work properly for
 language defined types such as Unbounded_String?  (Yes.)
 
@@ -85,11 +98,28 @@
     always be defined in terms of the 'Read and 'Write for the
     tagged type, preceded with the discriminants, if any.
 
-For untagged derived types, there is no problem for the derived
-type inheriting the stream attributes.  Even for tagged derived
+For untagged derived types, there is no (new) problem for the
+derived type inheriting the stream attributes. Even for tagged derived
 types, if the extension part is null, the 'Read and 'Write will
 effectively be inherited.
 
+We must take care, however, that all of the components have the appropriate
+attributes. For a limited type extension, the extension component could be
+of a type that does not have an implementation of Write or Read. In that
+case, we must take care to insure that the attribute for the new type cannot
+be called, either. (A alternative would be to inherit the original
+operation unmodified, but this would silently ignore the extension components.
+This could cause hard-to-find bugs as the components would probably revert to
+default values when they are input. This is similar to the way that
+functions of type extensions are inherited: they aren't inherited, they
+must be overridden.
+
+Clearly, the properties of the default implementation for the stream
+attributes can change for derived types (as in the example given in
+the question). Thus, we always want to use a "fresh" default
+implementation for an attribute, rather than inheriting a default
+implementation from the parent type.
+
 For language defined nonlimited private types, the RM does not say
 whether the stream-oriented attributes must work properly.  It seems
 that they ought to.  For many such types, the default version will work
@@ -129,12 +159,43 @@
 first subtype of the parent type. An inherited aspect of representation is
 overridden by a subsequent representation item that specifies the same aspect
 of the type or subtype.
+
+In contrast, whether operational aspects are inherited for a derived type
+depends on the specific aspect. When operational aspects are inherited for a
+derived type, aspects that were directly specified before the declaration of the
+derived type, or (in the case where the parent is derived) that were inherited
+by the parent type from the grandparent type are inherited. An inherited
+operational aspect is overridden by a subsequent operational item that specifies
+the same aspect of the type.
+
+!corrigendum 13.1(18)
+
+@dinsa
+@xbullet<If an aspect of representation is not specified, it is chosen by
+default in an unspecified manner.>
+@dinst
+If an operational aspect is @i<specified> for an entity (meaning that it is
+either directly specified or inherited), then that aspect of the entity is as
+specified. Otherwise, the aspect of the entity has the default value
+determined by the specific aspect.
 
-In contrast, operational aspects are not inherited for derived types; rather,
-the predefined value of each aspect is used. A predefined operational aspect
-can be overridden by a subsequent operational item that specifies the same
-aspect of the type.
+!corrigendum 13.3(75)
 
+@drepl
+@xhang<@xterm<S'External_Tag>S'External_Tag denotes an external string
+representation for S'Tag; it is of type String. External_Tag may be specified
+for a specific tagged type via an @fa<attribute_definition_clause>; the
+expression of such a clause shall be static. The default external tag
+representation is implementation-defined. See 3.9.2 and 13.13.2.>
+@dby
+@xhang<@xterm<S'External_Tag>S'External_Tag denotes an external string
+representation for S'Tag; it is of type String. External_Tag may be specified
+for a specific tagged type via an @fa<attribute_definition_clause>; the
+expression of such a clause shall be static. The default external tag
+representation is implementation-defined. See 3.9.2 and 13.13.2. The value
+of External_Tag is never inherited; the default value is always used unless
+it is directly specified for a type.>
+
 !corrigendum 13.13.02(9)
 
 @drepl
@@ -146,6 +207,13 @@
 an array type. If @i<T> is a discriminated type, discriminants are included only
 if they have defaults. If @i<T> is a tagged type, the tag is not included.
 @dby
+For untagged derived types, the Write or Read attribute of the parent type is
+inherited if it was directly specified for some ancestor type; otherwise, the
+default implementation of the attribute is used. For other derived types, the
+Write or Read attribute is not inherited; the default implementation is always
+used.
+
+The default implementation of Write and Read attributes is defined as follows:@hr
 For elementary types, the representation in terms of stream elements is
 implementation defined. For composite types, the Write or Read attribute for
 each component is called in a canonical order. The canonical order of
@@ -155,41 +223,26 @@
 if they have defaults. If @i<T> is a tagged type, the tag is not included.
 For nonlimited type extensions, the Write or Read attribute for the parent type
 is called, followed by the Write or Read attribute of each non-inherited
-component, in canonical order. For other derived types, the Write or Read
-attribute of the parent type is called.
+component, in canonical order.
 
-!corrigendum 13.13.02(26)
+!corrigendum 13.13.02(25)
 
 @drepl
-@xbullet<If @i<T> is an array type, S'Output first writes the bounds, and
-S'Input first reads the bounds.  If @i<T> has discriminants without defaults,
-S'Output first writes the discriminants (using S'Write for each), and S'Input
-first reads the discriminants (using S'Read for each).>
+Unless overridden by an @fa<attribute_definition_clause>, these subprograms
+execute as follows:
 @dby
-@xbullet<If @i<T> is an untagged derived type, the Output or Input attribute
-of the parent type is called, if one exists.>
-@xbullet<For other types:>
-@xinbull<If @i<T> is an array type, S'Output first writes the bounds, and
-S'Input first reads the bounds.  If @i<T> has discriminants without defaults,
-S'Output first writes the discriminants (using S'Write for each), and S'Input
-first reads the discriminants (using S'Read for each).>
+For untagged derived types, the Output or Input attribute of the parent type is
+inherited if it was directly specified for some ancestor type; otherwise, the
+default implementation of the attribute is used. For other derived types, the
+Output or Input attribute is not inherited; the default implementation is always
+used.
 
-!corrigendum 13.13.02(27)
+The default implementation of the Output and Input operations execute as
+follows:
 
-@drepl
-@xbullet<S'Output then calls S'Write to write the value of Item to the
-stream. S'Input then creates an object (with the bounds or
-discriminants, if any, taken from the stream), initializes it
-with S'Read, and returns the value of the object.>
-@dby
-@xinbull<S'Output then calls S'Write to write the value of Item to the
-stream. S'Input then creates an object (with the bounds or
-discriminants, if any, taken from the stream), initializes it
-with S'Read, and returns the value of the object.>
-
 !corrigendum 13.13.02(36)
 
-@dinsa
+@drepl
 The stream-oriented attributes may be specified for any type via an
 @fa<attribute_definition_clause>. All nonlimited types have default
 implementations for these operations. An @fa<attribute_reference> for one of
@@ -199,7 +252,19 @@
 subtype of the Item parameter shall be the base subtype if scalar, and the
 first subtype otherwise. The same rule applies to the result of the Input
 function.
-@dinss
+@dby
+The stream-oriented attributes may be specified for any type via an
+@fa<attribute_definition_clause>. All nonlimited types have default
+implementations for these operations. An @fa<attribute_reference> for one of
+these attributes is illegal if the type is limited, unless the attribute
+has been specified by an @fa<attribute_definition_clause> or (for a type
+extension) all of the attributes called by the default implementation can be
+referenced by this rule. For an
+@fa<attribute_definition_clause> specifying one of these attributes, the
+subtype of the Item parameter shall be the base subtype if scalar, and the
+first subtype otherwise. The same rule applies to the result of the Input
+function.
+
 For every subtype S of a language-defined nonlimited specific type @i<T>, the
 output generated by S'Output or S'Write shall be readable by S'Input or
 S'Read, respectively. The object read by S'Input or S'Read shall behave as
@@ -719,5 +784,153 @@
         -- an interaction argument for AI-137. This seems to be the only solution
         -- that would keep us on schedule. But it is pretty severe, as we're
         -- delaying answering these questions for more time.
+
+****************************************************************
+
+From:	Randy Brukardt
+Sent:	Thursday, June 01, 2000 6:34 PM
+
+Despite Tucker's violation of the our corrigendum rule (if you want a wording
+change, you have to propose one), I've made an attempt to rewrite this AI to
+address his concerns. I've also added points 3 and 5 from AI-195 to the
+discussion of this AI, as they are addressed in the corrigendum wording.
+
+Here is my latest cut at the wording:
+
+Replace 13.1(15) by the following (the first paragraph is unchanged from the
+previous Corrigendum):
+
+A derived type inherits each type-related aspect of representation of its parent
+type that was directly specified before the declaration of the derived type, or
+(in the case where the parent is derived) that was inherited by the parent type
+from the grandparent type. A derived subtype inherits each subtype-specific
+aspect of representation of its parent subtype that was directly specified
+before the declaration of the derived type, or (in the case where the parent is
+derived) that was inherited by the parent subtype from the grandparent subtype,
+but only if the parent subtype statically matches the first subtype of the
+parent type. An inherited aspect of representation is overridden by a subsequent
+representation item that specifies the same aspect of the type or subtype.
+
+In contrast, whether operational aspects are inherited for a derived type
+depends on the specific aspect. When operational aspects are inherited for a
+derived type, aspects that were directly specified before the declaration of the
+derived type, or (in the case where the parent is derived) that were inherited
+by the parent type from the grandparent type are inherited. An inherited
+operational aspect is overridden by a subsequent operational item that specifies
+the same aspect of the type.
+
+Add after 13.1(18):
+
+If an operational aspect is specified for an entity (meaning that it is either
+directly specified or inherited), then that aspect of the entity is as
+specified. Otherwise, the aspect of the entity has the default value determined
+by the specific aspect.
+
+Replace 13.3(75) by:
+
+S'External_Tag  S'External_Tag denotes an external string representation for
+S'Tag; it is of type String. External_Tag may be specified for a specific tagged
+type via an attribute_definition_clause; the expression of such a clause shall
+be static. The default external tag representation is implementation-defined.
+See 3.9.2 and 13.13.2. The value of External_Tag is never inherited[; the
+default value is always used unless it is directly specified for a type].
+
+Replace 13.13.2(9) by:
+
+For untagged derived types, the Write or Read attribute of the parent type is
+inherited if it was directly specified for some ancestor type; otherwise, the
+default implementation of the attribute is used. For other derived types, the
+Write or Read attribute is not inherited; the default implementation is always
+used.
+
+The default implementation of Write and Read attributes is defined as follows:
+For elementary types, the representation in terms of stream elements is
+implementation defined. For composite types, the Write or Read attribute for
+each component is called in a canonical order. The canonical order of components
+is last dimension varying fastest for an array, and positional aggregate order
+for a record. Bounds are not included in the stream if T is an array type. If T
+is a discriminated type, discriminants are included only if they have defaults.
+If T is a tagged type, the tag is not included. For type extensions, the Write
+or Read attribute for the parent type is called, followed by the Write or Read
+attribute of each non-inherited component, in canonical order.
+
+Replace 13.13.2(25) by:
+
+For untagged derived types, the Output or Input attribute of the parent type is
+inherited if it was directly specified for some ancestor type; otherwise, the
+default implementation of the attribute is used. For other derived types, the
+Output or Input attribute is not inherited; the default implementation is always
+used.
+
+The default implementation of the Output and Input operations execute as
+follows:
+
+Replace 13.13.2(36) by:
+
+The stream-oriented attributes may be specified for any type via an
+attribute_definition_clause. All nonlimited types have default implementations
+for these operations. An attribute_reference for one of these attributes is
+illegal if the type is limited, unless the attribute has been specified by an
+attribute_definition_clause or (for a type extension) all of the attributes
+called by the default implementation can be referenced by this rule. For an
+attribute_definition_clause specifying one of these attributes, the subtype of
+the Item parameter shall be the base subtype if scalar, and the first subtype
+otherwise. The same rule applies to the result of the Input function.
+
+
+(The changes previously proposed for 13.13.2(26-27) are removed.)
+
+-----
+
+Notes:
+
+I used square brackets above in the manner of the AARM. These don't appear in
+the corrigendum.
+
+13.1(18) is in fact wrong for 'Read/'Write/'Input/'Output as the default value
+is determined by the various rules; it certainly is not "chosen in an
+unspecified manner". Another reason to define operational attributes...
+
+13.3(75) needed to be changed to say that 'External_Tag values are never
+inherited.
+
+13.13.2(9) needed to say that default definitions are never inherited, only
+specified ones. (This is point 5 from the unfinished AI-195 -- the discriminants
+included may be different, and we don't want to write both sets). This could be
+removed (given that AI-195 wasn't finished), but doing so doesn't help the
+wording much.
+
+It also needed to name the "default implementations" (or some similar term);
+otherwise, it gets very awkward.
+
+Finally, (of course), it needed to say that untagged types inherit these
+aspects, while tagged types do not. Note that all type extensions inherit their
+components. See below for more on this.
+
+13.13.2(25) needed wording similar to 13.13.2(9). Note that this wording is
+repeated here in case it needs to be different from that in 13.13.2(9) [which
+would be the case if I lose the argument over 195 pt. 3 for instance]; these
+attributes are sufficiently different to treat them separately.
+
+13.13.2(36) needed wording to allow calling Read and Write for limited type
+extensions when all of the attributes that make up the extension exist.
+
+This purposely is a different conclusion than the unfinished AI-195 pt. 3 comes
+to. However, just inheriting existing attributes (thus silently ignoring any
+extension components) seems to be more likely to cause bugs than provide
+anything useful. Ada 95 goes to pretty far to avoid silently dropping extension
+components, yet a distributed system using these attributes could very well end
+up ignoring the extensions completely. This rule (combined with the new
+13.13.2(9)) allows limited extensions to work properly so long as all of the
+attributes are well defined. If any of them are not defined (either because they
+are limited and are not specified), then the attributes cannot be called. This
+seems to provide the maximum compatibility with the old, buggy rules (we get
+inheritance for null extensions, and we get inheritance with extension if all of
+the components are non-limited or have specified attributes), while preventing
+the bugs caused by silently ignoring components. I suspect that this change
+would find/fix more bugs than breaking correct programs. And the fix is easy if
+a user *really* wants inheritance without the extension components: just add an
+attribute_clause for the appropriate routine (presumably inherited as well - it
+has to be primitive for the parent type).
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent