Annotated Ada Reference ManualLegal Information
Table of Contents   Index   References   Search   Previous   Next 

 13.13.2 Stream-Oriented Attributes

1/1
{8652/0009} {AI95-00137-01} The operational attributes Write, Read, Output, and Input attributes convert values to a stream of elements and reconstruct values from a stream. 

Static Semantics

1.1/2
  {AI95-00270-01} For every subtype S of an elementary type T, the following representation attribute is defined: 
1.2/2
  S'Stream_Size

{AI95-00270-01} Denotes the number of bits occupied in a stream by items of subtype S. Hence, the number of stream elements required per item of elementary type T is:
1.3/2
T'Stream_Size / Ada.Streams.Stream_Element'Size
1.4/2
The value of this attribute is of type universal_integer and is a multiple of Stream_Element'Size.
1.5/2
Stream_Size may be specified for first subtypes via an attribute_definition_clause; the expression of such a clause shall be static, nonnegative, and a multiple of Stream_Element'Size. 
1.a/2
Discussion: Stream_Size is a type-related attribute (see 13.1).

Implementation Advice

1.6/2
  {AI95-00270-01} If not specified, the value of Stream_Size for an elementary type should be the number of bits that corresponds to the minimum number of stream elements required by the first subtype of the type, rounded up to the nearest factor or multiple of the word size that is also a multiple of the stream element size. 
1.b/2
Implementation Advice: If not specified, the value of Stream_Size for an elementary type should be the number of bits that corresponds to the minimum number of stream elements required by the first subtype of the type, rounded up to the nearest factor or multiple of the word size that is also a multiple of the stream element size.
1.c/2
Reason: {AI95-00270-01} This is Implementation Advice because we want to allow implementations to remain compatible with their Ada 95 implementations, which may have a different handling of the number of stream elements. Users can always specify Stream_Size if they need a specific number of stream elements. 
1.7/2
  {AI95-00270-01} {recommended level of support (Stream_Size attribute) [partial]} The recommended level of support for the Stream_Size attribute is:
1.8/2
1.d/2
Implementation Advice: The recommended level of support for the Stream_Size attribute should be followed.
1.e/2
Ramification: There are no requirements beyond supporting confirming Stream_Size clauses for floating point and access types. Floating point and access types usually only have a handful of defined formats, streaming anything else makes no sense for them.
1.f/2
For discrete and fixed point types, this may require support for sizes other than the “natural” ones. For instance, on a typical machine with 32-bit integers and a Stream_Element'Size of 8, setting Stream_Size to 24 must be supported. This is required as such formats can be useful for interoperability with unusual machines, and there is no difficulty with the implementation (drop extra bits on output, sign extend on input). 

Static Semantics

2
For every subtype S of a specific type T, the following attributes are defined. 
3
S'Write
S'Write denotes a procedure with the following specification: 
4/2
{AI-00441-01} procedure S'Write(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : in T)
5
S'Write writes the value of Item to Stream.
6
S'Read
S'Read denotes a procedure with the following specification: 
7/2
{AI-00441-01} procedure S'Read(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : out T)
8
S'Read reads the value of Item from Stream
8.1/2
  {8652/0040} {AI95-00108-01} {AI95-00444-01} For an untagged derived type types, the Write (resp. and Read) attribute is attributes are inherited according to the rules given as specified in 13.1 if the attribute is available for the parent type at the point where T is declared. For a tagged derived type, these attributes are not inherited, but rather; otherwise, the default implementations of these attributes are used. The default implementations of Write and Read attributes execute as follows:
8.2/2
  {AI95-00444-01} The default implementations of the Write and Read attributes, where available, execute as follows:
9/2
{8652/0040} {AI95-00108-01} {AI95-00195-01} {AI95-00251-01} {AI95-00270-01} For elementary types, Read reads (and Write writes) the number of stream elements implied by the Stream_Size for the type T; the representation in terms of those stream elements is implementation defined. For composite types, the Write or Read attribute for each component is called in a canonical order, which. 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 component of the extension part, in canonical order. For a limited type extension, if the attribute of the parent any ancestor type or any progenitor type of T is available anywhere within the immediate scope of T, has been directly specified and the attribute of the parent type or any ancestor type of the type of any of the extension components is not available at the freezing point of T, then which are of a limited type has not been specified, the attribute of T shall be directly specified.
9.a/2
Implementation defined: The contents of the stream elements read and written representation used by the Read and Write attributes of elementary types in terms of stream elements.
9.b
Reason: A discriminant with a default value is treated simply as a component of the object. On the other hand, an array bound or a discriminant without a default value, is treated as “descriptor” or “dope” that must be provided in order to create the object and thus is logically separate from the regular components. Such “descriptor” data are written by 'Output and produced as part of the delivered result by the 'Input function, but they are not written by 'Write nor read by 'Read. A tag is like a discriminant without a default.
9.b.1/1
{8652/0040} {AI95-00108-01} For limited type extensions, we must have a definition of 'Read and 'Write if the parent type has one, as it is possible to make a dispatching call through the attributes. The rule is designed to automatically do the right thing in as many cases as possible.
9.b.2/1
{AI95-00251-01} Similarly, a type that has a progenitor with an available attribute must also have that attribute, for the same reason.
9.c/2
Ramification: {AI95-00195-01} For a composite object, the subprogram denoted by the Write or Read attribute of each component is called, whether it is the default or is user-specified. Implementations are allowed to optimize these calls (see below), presuming the properties of the attributes are preserved. 
9.1/2
  {AI95-00270-01} Constraint_Error is raised by the predefined Write attribute if the value of the elementary item is outside the range of values representable using Stream_Size bits. For a signed integer type, an enumeration type, or a fixed point type, the range is unsigned only if the integer code for the lower bound of the first subtype is nonnegative, and a (symmetric) signed range that covers all values of the first subtype would require more than Stream_Size bits; otherwise the range is signed.
10
For every subtype S'Class of a class-wide type T'Class: 
11
S'Class'Write
S'Class'Write denotes a procedure with the following specification: 
12/2
{AI-00441-01} procedure S'Class'Write(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item   : in T'Class)
13
Dispatches to the subprogram denoted by the Write attribute of the specific type identified by the tag of Item.
14
S'Class'Read
S'Class'Read denotes a procedure with the following specification: 
15/2
{AI-00441-01} procedure S'Class'Read(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : out T'Class)
16
Dispatches to the subprogram denoted by the Read attribute of the specific type identified by the tag of Item. 
16.a
Reason: It is necessary to have class-wide versions of Read and Write in order to avoid generic contract model violations; in a generic, we don't necessarily know at compile time whether a given type is specific or class-wide. 

Implementation Advice

17/2
 This paragraph was deleted.{AI95-00270-01} If a stream element is the same size as a storage element, then the normal in-memory representation should be used by Read and Write for scalar objects. Otherwise, Read and Write should use the smallest number of stream elements needed to represent all values in the base range of the scalar type. 

Static Semantics

18
For every subtype S of a specific type T, the following attributes are defined. 
19
S'Output
S'Output denotes a procedure with the following specification: 
20/2
{AI-00441-01} procedure S'Output(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item : in T)
21
S'Output writes the value of Item to Stream, including any bounds or discriminants. 
21.a
Ramification: Note that the bounds are included even for an array type whose first subtype is constrained. 
22
S'Input
S'Input denotes a function with the following specification: 
23/2
{AI-00441-01} function S'Input(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class)
   return T
24
S'Input reads and returns one value from Stream, using any bounds or discriminants written by a corresponding S'Output to determine how much to read. 
25/2
 {8652/0040} {AI95-00108-01} {AI95-00444-01} For an untagged derived type types, the Output (resp. and Input) attribute is attributes of the parent type are inherited according to the rules given as specified in 13.1 if the attribute is available for the parent type at the point where T is declared. For a tagged derived type, these attributes are not inherited, but rather; otherwise, the default implementations of these attributes are used. The default implementations of Output and Input attributes execute as follows: Unless overridden by an attribute_definition_clause, these subprograms execute as follows:
25.1/2
   {AI95-00444-01} The default implementations of the Output and Input attributes, where available, execute as follows: 
26
27/2
27.1/2
   {AI95-00251-01} If T is an abstract type, then S'Input is an abstract function.
27.a/2
Ramification: For an abstract type T, S'Input can be called in a dispatching call, or passed to a abstract formal subprogram. But it cannot be used in non-dispatching contexts, because we don't allow objects of abstract types to exist. The designation of this function as abstract has no impact on descendants of T, as T'Input is not inherited for tagged types, but rather recreated (and the default implementation of T'Input calls T'Read, not the parent type's T'Input). Note that T'Input cannot be specified in this case, as any function with the proper profile is necessarily abstract, and specifying abstract subprograms in an attribute_definition_clause is illegal. 
28
For every subtype S'Class of a class-wide type T'Class: 
29
S'Class'Output

S'Class'Output denotes a procedure with the following specification: 
30/2
{AI-00441-01} procedure S'Class'Output(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class;
   Item   : in T'Class)
31/2
{AI95-00344-01} First writes the external tag of Item to Stream (by calling String'Output(StreamTags.External_Tag(Item'Tag)) — see 3.9) and then dispatches to the subprogram denoted by the Output attribute of the specific type identified by the tag. Tag_Error is raised if the tag of Item identifies a type declared at an accessibility level deeper than that of S. 
31.a/2
Reason: {AI95-00344-01} We raise Tag_Error here for nested types as such a type cannot be successfully read with S'Class'Input, and it doesn't make sense to allow writing a value that cannot be read. 
32
S'Class'Input
S'Class'Input denotes a function with the following specification: 
33/2
{AI-00441-01} function S'Class'Input(
   Stream : not null access Ada.Streams.Root_Stream_Type'Class)
   return T'Class
34/2
{AI95-00279-01} {AI95-00344-01} First reads the external tag from Stream and determines the corresponding internal tag (by calling Tags.Descendant_Tag Internal_Tag(String'Input(Stream), S'Tag) which might raise Tag_Error — see 3.9) and then dispatches to the subprogram denoted by the Input attribute of the specific type identified by the internal tag; returns that result. If the specific type identified by the internal tag is not covered by T'Class or is abstract, Constraint_Error is raised. 
35/2
 {AI95-00195-01} {Range_Check [partial]} {check, language-defined (Range_Check)} In the default implementation of Read and Input for a composite type, for each scalar component that is a discriminant or whose component_declaration includes a default_expression, a check is made that the value returned by Read for the component belongs to its subtype. {Constraint_Error (raised by failure of run-time check)} Constraint_Error is raised if this check fails. For other scalar components, no check is made. For each component that is of an access type, if the implementation can detect that the value returned by Read for the component is not a value of its subtype, Constraint_Error is raised. If the value is not a value of its subtype and this error is not detected, the component has an abnormal value, and erroneous execution can result (see 13.9.1). In the default implementation of Read for a composite type with defaulted discriminants, if the actual parameter of Read is constrained, a check is made that the discriminants read from the stream are equal to those of the actual parameter. Constraint_Error is raised if this check fails.
36/2
 {AI95-00195-01} {unspecified [partial]} It is unspecified at which point and in which order these checks are performed. In particular, if Constraint_Error is raised due to the failure of one of these checks, it is unspecified how many stream elements have been read from the stream.
37/1
 {8652/0045} {AI95-00132-01} {End_Error (raised by failure of run-time check)} In the default implementation of Read and Input for a type, End_Error is raised if the end of the stream is reached before the reading of a value of the type is completed.
38/2
 {8652/0040} {AI95-00108-01} {AI95-00195-01} {AI95-00251-01} {specifiable (of Read for a type) [partial]} {specifiable (of Write for a type) [partial]} {specifiable (of Input for a type) [partial]} {specifiable (of Output for a type) [partial]} {Read clause} {Write clause} {Input clause} {Output clause} The stream-oriented attributes may be specified for any type via an attribute_definition_clause. The subprogram name given in such a clause shall not denote an abstract subprogram. Furthermore, if a stream-oriented attribute is specified for an interface type by an attribute_definition_clause, the subprogram name given in the clause shall statically denote a null procedure. 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)] the attribute has been specified for an ancestor type. 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. 
38.a/2
This paragraph was deleted.Reason: {AI95-00195-01} This is to simplify implementation. 
38.a.1/2
This paragraph was deleted.Discussion: {8652/0040} {AI95-00108-01} {AI95-00195-01} “Specified” includes inherited attributes, and default implementations are never inherited. So, for untagged limited types, the second part of the attribute_reference rule has the same meaning as the first part. However, tagged types never inherit attributes, so the second rule is needed so that the default implementations for the attributes can be called when those are constructed from a directly specified ancestor.
38.b/2
Discussion: {AI95-00251-01} Stream attributes (other than Input) are always null procedures for interface types (they have no components). We need to allow explicit setting of the Read and Write attributes in order that the class-wide attributes like LI'Class'Input can be made available. (In that case, any descendant of the interface type would require available attributes.) But we don't allow any concrete implementation because these don't participate in extensions (unless the interface is the parent type). If we didn't ban concrete implementations, the order of declaration of a pair of interfaces would become significant. For example, if Int1 and Int2 are interfaces with concrete implementations of 'Read, then the following declarations would have different implementations for 'Read:
38.c/2
type Con1 is new Int1 and Int2 with null record;
type Con2 is new Int2 and Int1 with null record;
38.d/2
This would violate our design principle that the order of the specification of the interfaces in a derived_type_definition doesn't matter. 
38.e/2
Ramification: The Input attribute cannot be specified for an interface. As it is a function, a null procedure is impossible; a concrete function is not possible anyway as any function returning an abstract type must be abstract. And we don't allow specifying stream attributes to be abstract subprograms. This has no impact, as the availability of Int'Class'Input (where Int is a limited interface) depends on whether Int'Read (not Int'Input) is specified. There is no reason to allow Int'Output to be specified, either, but there is equally no reason to disallow it, so we don't have a special rule for that. 
38.f/2
Discussion: {AI95-00195-01} Limited types generally do not have default implementations of the stream-oriented attributes. The rules defining when a stream-oriented attribute is available (see below) determine when an attribute of a limited type is in fact well defined and usable. The rules are designed to maximize the number of cases in which the attributes are usable. For instance, when the language provides a default implementation of an attribute for a limited type based on a specified attribute for the parent type, we want to be able to call that attribute. 
39/2
 {AI95-00195-01} A stream-oriented attribute for a subtype of a specific type T is available at places where one of the following conditions is true: {available (stream attribute)}
40/2
41/2
41.a/2
Reason: In this case, the language provides a well-defined default implementation, which we want to be able to call. 
42/2
42.a/2
Reason: Attributes are only inherited for untagged derived types, and surely we want to be able to call inherited attributes. 
43/2
43.a/2
Reason: The default implementation of Input and Output are based on Read and Write; so if the implementation of Read or Write is good, so is the matching implementation of Input or Output. 
44/2
44.a/2
Reason: We always want to allow calling a specified attribute. But we don't want availability to break privacy. Therefore, only attributes whose specification can be seen count. Yes, we defined the visibility of an attribute_definition_clause (see 8.3). 
45/2
 {AI95-00195-01} A stream-oriented attribute for a subtype of a class-wide type T'Class is available at places where one of the following conditions is true:
46/2
47/2
48/2
48.a/2
Reason: The rules are stricter for class-wide attributes because (for the default implementation) we must ensure that any specific attribute that might ever be dispatched to is available. Because we require specification of attributes for extensions of limited parent types with available attributes, we can in fact know this. Otherwise, we would not be able to use default class-wide attributes with limited types, a significant limitation. 
49/2
 {AI95-00195-01} An attribute_reference for one of the stream-oriented attributes is illegal unless the attribute is available at the place of the attribute_reference. Furthermore, an attribute_reference for T'Input is illegal if T is an abstract type.
49.a/2
Discussion: Stream attributes always exist. It is illegal to call them in some cases. Having the attributes not be defined for some limited types would seem to be a cleaner solution, but it would lead to contract model problems for limited private types.
49.b/2
T'Input is available for abstract types so that T'Class'Input is available. But we certainly don't want to allow calls that could create an object of an abstract type. Remember that T'Class is never abstract, so the above legality rule doesn't apply to it. We don't have to discuss whether the attribute is specified, as it cannot be: any function returning the type would have to be abstract, and we do not allow specifying an attribute with an abstract subprogram. 
50/2
 {AI95-00195-01} In the parameter_and_result_profiles for the stream-oriented attributes, the subtype of the Item parameter is the base subtype of T if T is a scalar type, and the first subtype otherwise. The same rule applies to the result of the Input attribute.
51/2
 {AI95-00195-01} 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.
51.a/2
Reason: This is to simplify implementation. 
51.b/2
Ramification: The view of the type at the point of the attribute_definition_clause determines whether the first subtype or base subtype is required. Thus, for a scalar type with a partial view (which is never scalar), whether the first subtype or the base subtype is required is determined by whether the attribute_definition_clause occurs before or after the full definition of the scalar type. 
52/2
 {AI95-00366-01} {support external streaming} {external streaming (type supports)} [A type is said to support external streaming if Read and Write attributes are provided for sending values of such a type between active partitions, with Write marshalling the representation, and Read unmarshalling the representation.] A limited type supports external streaming only if it has available Read and Write attributes. A type with a part that is of an access type supports external streaming only if that access type or the type of some part that includes the access type component, has Read and Write attributes that have been specified via an attribute_definition_clause, and that attribute_definition_clause is visible. [An anonymous access type does not support external streaming. ]All other types support external streaming.
52.a/2
Ramification: A limited type with a part that is of an access type needs to satisfy both rules. 

Erroneous Execution

53/2
 {AI95-00279-01} {AI95-00344-01} {erroneous execution (cause) [partial]} If the internal tag returned by Descendant_Tag to T'Class'Input identifies a type that is not library-level and whose tag has not been created, or does not exist in the partition at the time of the call, execution is erroneous.
53.a/2
Ramification: The definition of Descendant_Tag prevents such a tag from being provided to T'Class'Input if T is a library-level type. However, this rule is needed for nested tagged types. 

Implementation Requirements

54/1
 {8652/0040} {AI95-00108-01} For every subtype S of a language-defined nonlimited specific type T, the output generated by S'Output or S'Write shall be readable by S'Input or S'Read, respectively. This rule applies across partitions if the implementation conforms to the Distributed Systems Annex.
55/2
 {AI95-00195-01} If Constraint_Error is raised during a call to Read because of failure of one the above checks, the implementation must ensure that the discriminants of the actual parameter of Read are not modified. 

Implementation Permissions

56/2
 {AI95-00195-01} The number of calls performed by the predefined implementation of the stream-oriented attributes on the Read and Write operations of the stream type is unspecified. An implementation may take advantage of this permission to perform internal buffering. However, all the calls on the Read and Write operations of the stream type needed to implement an explicit invocation of a stream-oriented attribute must take place before this invocation returns. An explicit invocation is one appearing explicitly in the program text, possibly through a generic instantiation (see 12.3). 
NOTES
57
34  For a definite subtype S of a type T, only T'Write and T'Read are needed to pass an arbitrary value of the subtype through a stream. For an indefinite subtype S of a type T, T'Output and T'Input will normally be needed, since T'Write and T'Read do not pass bounds, discriminants, or tags.
58
35  User-specified attributes of S'Class are not inherited by other class-wide types descended from S. 

Examples

59
Example of user-defined Write attribute: 
60/2
{AI95-00441-01} procedure My_Write(
  Stream : not null access Ada.Streams.Root_Stream_Type'Class;
  
Item   : My_Integer'Base);
for My_Integer'Write use My_Write;
60.a
Discussion: Example of network input/output using input output attributes:
60.b
with Ada.Streams; use Ada.Streams;
generic
    type Msg_Type(<>) is private;
package Network_IO is
    -- Connect/Disconnect are used to establish the stream
    procedure Connect(...);
    procedure Disconnect(...);
60.c
    -- Send/Receive transfer messages across the network
    procedure Send(X : in Msg_Type);
    function Receive return Msg_Type;
private
    type Network_Stream is new Root_Stream_Type with ...
    procedure Read(...);  -- define Read/Write for Network_Stream
    procedure Write(...);
end Network_IO;
60.d
with Ada.Streams; use Ada.Streams;
package body Network_IO is
    Current_Stream : aliased Network_Stream;
    . . .
    procedure Connect(...) is ...;
    procedure Disconnect(...) is ...;
60.e
    procedure Send(X : in Msg_Type) is
    begin
        Msg_Type'Output(Current_Stream'Access, X);
    end Send;
60.f
    function Receive return Msg_Type is
    begin
        return Msg_Type'Input(Current_Stream'Access);
    end Receive;
end Network_IO;

Inconsistencies With Ada 95

60.g/2
{8652/0040} {AI95-00108-01} {inconsistencies with Ada 95} Corrigendum: Clarified how the default implementation for stream attributes is determined (eliminating conflicting language). The new wording provides that attributes for type extensions are created by composing the parent's attribute with those for the extension components if any. If a program was written assuming that the extension components were not included in the stream (as in original Ada 95), it would fail to work in the language as corrected by the Corrigendum.
60.h/2
{AI95-00195-01} Amendment Correction: Explicitly provided a permission that the number of calls to the underlying stream Read and Write operations may differ from the number determined by the canonical operations. If Ada 95 code somehow depended on the number of calls to Read or Write, it could fail with an Ada 2005 implementation. Such code is likely to be very rare; moreover, such code is really wrong, as the permission applies to Ada 95 as well. 

Extensions to Ada 95

60.i/2
{AI95-00270-01} {extensions to Ada 95} The Stream_Size attribute is new. It allows specifying the number of bits that will be streamed for a type. The Implementation Advice involving this also was changed; this is not incompatible because Implementation Advice does not have to be followed.
60.j/2
{8652/0040} {AI95-00108-01} {AI95-00195-01} {AI95-00444-01} Corrigendum: Limited types may have default constructed attributes if all of the parent and (for extensions) extension components have available attributes. Ada 2005 adds the notion of availability to patch up some holes in the Corrigendum model. 

Wording Changes from Ada 95

60.k/2
{8652/0009} {AI95-00137-01} Corrigendum: Added wording to specify that these are operational attributes.
60.l/2
{8652/0045} {AI95-00132-01} Corrigendum: Clarified that End_Error is raised by the default implementation of Read and Input if the end of the stream is reached. (The result could have been abnormal without this clarification, thus this is not an inconsistency, as the programmer could not have depended on the previous behavior.)
60.m/2
{AI95-00195-01} Clarified that the default implementation of S'Input does normal initialization on the object that it passes to S'Read.
60.n/2
{AI95-00195-01} Explicitly stated that what is read from a stream when a required check fails is unspecified.
60.o/2
{AI95-00251-01} Defined availability and default implementations for types with progenitors.
60.p/2
{AI95-00279-01} Specified that Constraint_Error is raised if the internal tag retrieved for S'Class'Input is for some type not covered by S'Class or is abstract. We also explicitly state that the program is erroneous if the tag has not been created or does not currently exist in the partition. (Ada 95 did not specify what happened in these cases; it's very unlikely to have provided some useful result, so this is not considered an inconsistency.)
60.q/2
{AI95-00344-01} Added wording to support nested type extensions. S'Input and S'Output always raise Tag_Error for such extensions, and such extensions were not permitted in Ada 95, so this is neither an extension nor an incompatibility.
60.r/2
{AI95-00366-01} Defined supports external streaming to put all of the rules about “good” stream attributes in one place. This is used for distribution and for defining pragma Pure.
60.s/2
{AI95-00441-01} Added the not null qualifier to the first parameter of all of the stream attributes, so that the semantics doesn't change between Ada 95 and Ada 2005. This change is compatible, because mode conformance is required for subprograms specified as stream attributes, and null_exclusions are not considered for mode conformance.
60.t/2
{AI95-00444-01} Improved the wording to make it clear that we don't define the default implementations of attributes that cannot be called (that is, aren't “available”). Also clarified when inheritance takes place. 

Table of Contents   Index   References   Search   Previous   Next 
Ada-Europe Sponsored by Ada-Europe