Version 1.2 of ais/ai-00137.txt

Unformatted version of ais/ai-00137.txt version 1.2
Other versions for file ais/ai-00137.txt

!standard 13.01 (10)          99-07-28 AI95-00137/02
!class binding interpretation 96-05-07
!status Corrigendum 2000 99-07-28
!status WG9 approved 96-12-07
!status ARG approved 6-0-2 96-06-17
!status work item 96-05-08
!status received 96-05-07
!priority High
!difficulty Medium
!subject Attribute definition clause for Stream Attributes
!summary
13.1(10) says:
10 For an untagged derived type, no type-related representation items are allowed if the parent type is a by-reference type, or has any user-defined primitive subprograms.
This rule does not apply to an attribute_definition_clause for one of the stream-oriented attributes Read, Write, Input, and Output.
!question
13.1(10) seems to forbid the following example:
with Ada.Streams; use Ada.Streams; generic type T is private; package Attr_Rep is type NT is new T; procedure Attribute_Write( Stream : access Root_Stream_Type'Class; Item : in NT); for NT'Write use Attribute_Write; -- Illegal? (No.) end Attr_Rep;
!recommendation
(See summary.)
!wording
(See corrigendum.)
!discussion
The intent of 13.1(10) is to forbid two types from having different representation in certain cases. However, the stream-oriented attributes, although they are formally defined to be "representation attributes", do not actually affect the representation of the type. Therefore, there is no need for 13.1(10) to apply to these attributes. Furthermore, as the example illustrates, applying the rule to these attributes would seriously hinder their usefulness.
!corrigendum 13.01(10)
Replace the paragraph:
For an untagged derived type, no type-related representation items are allowed if the parent type is a by-reference type, or has any user-defined primitive subprograms.
by:
For an untagged derived type, no type-related representation items, other than the stream-oriented attributes Read, Write, Input, and Output, are allowed if the parent type is a by-reference type, or has any user-defined primitive subprograms.
!corrigendum 13.01(11)
Replace the paragraph:
Representation aspects of a generic formal parameter are the same as those of the actual. A type-related representation item is not allowed for a descendant of a generic formal untagged type.
by:
Representation aspects of a generic formal parameter are the same as those of the actual. A type-related representation item, other than the stream-oriented attributes Read, Write, Input, and Output, is not allowed for a descendant of a generic formal untagged type.
!ACATS test
Create a C-Test to verify that Read/Write attributes can be defined on derived non-tagged types.
!appendix

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!from Anthony Gargaro 96-04-28
!keywords
!reference 96-5519.a Anthony Gargaro  96-4-28>>
!discussion stream attributes, representation items

A consequence of specifying attribute definition clauses for the stream
attributes is that the restrictions associated with representation items
hamper the use of stream attributes. For example, the following idiom is
illegal by 13.1(11).

with Ada.Streams; use Ada.Streams;
generic
  type T is private;
package Attr_Rep is
  type NT is new T;
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT);
  -- Illegal use of attribute definition clause
  for NT'Write use Attribute_Write;
end Attr_Rep;
package body Attr_Rep is
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT) is
  begin
    -- Save type information for dispatching Write and then call
    T'Write(Stream, T(Item));
  end Attribute_Write;
end Attr_Rep;

Since allowing such idioms facilitates reading/writing streams that are
architecture neutral, consideration should be given to relaxing the
application of 13.1(10,11) to representation-independent attributes.

****************************************************************

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!keywords stream attributes, representation items
!reference 96-5519.a Anthony Gargaro  96-4-28
!keywords stream attributes, representation items
!from Norman Cohen 96-04-29
!reference 96-5521.a Norman H. Cohen 96-4-29>>
!discussion

Interestingly, 13.1(11) does not prohibit the following workaround:

with Ada.Streams; use Ada.Streams;
generic
  type T is private;
package Attr_Rep is
  type NT is
     record
        Only_Component: T;
     end record;
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT);
  for NT'Write use Attribute_Write;
end Attr_Rep;
package body Attr_Rep is
  procedure Attribute_Write(
            Stream : access Root_Stream_Type'Class;
            Item   : in NT) is
  begin
    -- Save type information for dispatching Write and then call
    T'Write(Stream, Item.Only_Component);
  end Attribute_Write;
end Attr_Rep;

Of course this is a nuisance:  NT doesn't inherit T's operations, so one
always has to invoke Op(X.Only_Component) instead of Op(X).  One can
define corresponding operations for type NT manually, but there is no way
to allow direct conversions between descendents of NT and types that are
truly in the derivation class for T.  (One wishes to use NT rather than T
in constructing new types, so that the 'Write for the new type invokes
NT'Write.)

On the one hand, the existence of such a loophole indicates that there is
no fundamental problem with the relaxation Anthony suggests.  On the
other hand, the existence of the loophole may make resolution of the
problem a little less of an emergency.

****************************************************************

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!keywords stream attributes, representation items
!reference 96-5519.a Anthony Gargaro  96-4-28
!keywords stream attributes, representation items
!reference 96-5521.a Norman H. Cohen 96-4-29
!from Bob Duff
!reference 96-5542.a Robert A Duff 96-5-8>>
!discussion

Norm says:

> Interestingly, 13.1(11) does not prohibit the following workaround:
> [workaround involving wrapping the type in a record]

Right.  Another workaround is to simply make the thing a tagged type,
since 13.1(11) applies only to untagged types.

- Bob

****************************************************************

!section 13.1(10)
!subject Attribute definition clause for Stream Attributes
!reference RM95-13.1(10)
!reference RM95-13.1(11)
!reference RM95-13.13.2(36)
!reference 96-5519.a Anthony Gargaro  96-4-28
!reference 96-5521.a Norman H. Cohen 96-4-29
!reference 96-5542.a Robert A Duff 96-5-8
!from Anthony Gargaro 96-05-10
!reference 96-5546.a Anthony 96-5-10>>
!discussion

>>Norm says:

>> Interestingly, 13.1(11) does not prohibit the following workaround:
>> [workaround involving wrapping the type in a record]

to which Bob replied:

>Right.  Another workaround is to simply make the thing a tagged type,
>since 13.1(11) applies only to untagged types.

In the context of the application where this issue was raised both of these
options were considered. Unfortunately, neither seems satisfactory since the
useability of the abstraction which is presented to the programmer is
compromised. This is because the idiom requires the incremental composition of
types to allow arbitrary user-defined types to be associated with "architecture
neutral" stream attributes.

In the case of wrapping the type (which is used at the moment), there is a
useability penalty. The programmer must be aware of the wrapper name when
referencing subcomponents of the type and this may become onerous if the
composite type contains other composite types.


****************************************************************

Questions? Ask the ACAA Technical Agent