!standard 13.01 (10-11) 00-08-31 AI95-00137/08 !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 !qualifier Error !subject Attribute definition clause for stream attributes !summary 13.1(10) says: 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. The definition of stream attributes as "representation attributes" has proven to be a continuing problem. Several issues have made it necessary to exempt stream attributes from the rules for representation attributes; indeed the number of such exemptions makes it clear that it is confusing to classify them as representation attributes. Therefore, we have taken the major step of defining a new kind of attribute, the "operational attributes", and redefining stream attributes to be of this kind. In particular, 7.3(5), 13.1(10), and the last sentence of 13.1(11) are unchanged, so that these rules do not apply to operational items. None of these rules are necessary for these attributes. We've also left 3.8(11) unchanged, as an operational item cannot occur here. Changes to 13.1(15) and 13.1(18) are found in 8652/0040 (AI-00108). !corrigendum 3.08(05) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 3.11(04) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 9.01(05) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 9.01(12) @drepl As part of the initialization of a task object, any @fas and any per-object constraints associated with @fas of the corresponding @fa are elaborated in the given order. @dby As part of the initialization of a task object, any @fas and any per-object constraints associated with @fas of the corresponding @fa are elaborated in the given order. !corrigendum 9.04(05) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 9.04(08) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 13(01) @drepl This section describes features for querying and controlling aspects of representation and for interfacing to hardware. @dby This section describes features for querying and controlling certain aspects of entities and for interfacing to hardware. !corrigendum 13.01(00) @drepl Representation Items @dby Operational and Representation Items !corrigendum 13.01(01) @drepl There are three kinds of @i: @fas, @fas, and @i. Representation items specify how the types and other entities of the language are to be mapped onto the underlying machine. They can be provided to give more efficient representation or to interface with features that are outside the domain of the language (for example, peripheral hardware). Representation items also specify other specifiable properties of entities. A representation item applies to an entity identified by a @fa, which denotes an entity declared local to the current declarative region, or a library unit declared immediately preceding a representation pragma in a @fa. @dby Representation and operational items can be used to specify aspects of entities. Two kinds of aspects of entities can be specified: aspects of representation and operational aspects. Representation items specify how the types and other entities of the language are to be mapped onto the underlying machine. Operational items specify other properties of entities. There are six kinds of @i: @fas for representation attributes, @fas, @fas, @fas, @fas, and @i. They can be provided to give more efficient representation or to interface with features that are outside the domain of the language (for example, peripheral hardware). An @i is an @fa for an operational attribute. An operational item or a representation item applies to an entity identified by a @fa, which denotes an entity declared local to the current declarative region, or a library unit declared immediately preceding a representation pragma in a @fa. !corrigendum 13.01(02) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 13.01(04) @drepl @xindent or @fa is allowed.> @dby @xindent or @fa is allowed.> !corrigendum 13.01(05) @drepl In a representation item, if the @fa is a @fa, then it shall resolve to denote a declaration (or, in the case of a @fa, one or more declarations) that occurs immediately within the same @fa as the representation item. If the @fa has an @fa, then it shall resolve to denote an implementation-defined component (see 13.5.1) or a class-wide type implicitly declared immediately within the same @fa as the representation item. A @fa that is a @i@fa (only permitted in a representation pragma) shall resolve to denote the @fa that immediately precedes (except for other pragmas) the representation pragma. @dby In an operational item or representation item, if the @fa is a @fa, then it shall resolve to denote a declaration (or, in the case of a @fa, one or more declarations) that occurs immediately within the same @fa as the item. If the @fa has an @fa, then it shall resolve to denote an implementation-defined component (see 13.5.1) or a class-wide type implicitly declared immediately within the same @fa as the item. A @fa that is a @i@fa (only permitted in a representation pragma) shall resolve to denote the @fa that immediately precedes (except for other pragmas) the representation pragma. !corrigendum 13.01(06) @drepl The @fa of a @fa or representation pragma shall statically denote an entity (or, in the case of a @fa, one or more entities) declared immediately preceding it in a @fa, or within the same @fa, @fa, @fa, @fa, or @fa as the representation item. If a @fa denotes a local callable entity, it may do so through a local @fa (as a way to resolve ambiguity in the presence of overloading); otherwise, the @fa shall not denote a @fa. @dby The @fa of an @fa or representation pragma shall statically denote an entity (or, in the case of a @fa, one or more entities) declared immediately preceding it in a @fa, or within the same @fa, @fa, @fa, @fa, or @fa as the representation or operational item. If a @fa denotes a local callable entity, it may do so through a local @fa (as a way to resolve ambiguity in the presence of overloading); otherwise, the @fa shall not denote a @fa. !corrigendum 13.01(08) @dinsa A representation item @i an @i of the entity denoted by the @fa, except in the case of a type-related representation item, whose @fa shall denote a first subtype, and which directly specifies an aspect of the subtype's type. A representation item that names a subtype is either @i (Size and Alignment clauses) or @i (all others). Subtype-specific aspects may differ for different subtypes of the same type. @dinst An operational item @i an @i of the type of the subtype denoted by the @fa. The @fa of an operational item shall denote a first subtype. An operational item that names a subtype is type-related. !corrigendum 13.01(09) @dinsa A representation item that directly specifies an aspect of a subtype or type shall appear after the type is completely defined (see 3.11.1), and before the subtype or type is frozen (see 13.14). If a representation item is given that directly specifies an aspect of an entity, then it is illegal to give another representation item that directly specifies the same aspect of the entity. @dinst An operational item that directly specifies an aspect of a type shall appear before the type is frozen (see 13.14). If an operational item is given that directly specifies an aspect of a type, then it is illegal to give another operational item that directly specifies the same aspect of the type. !corrigendum 13.01(11) @drepl 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. @dby Operational and 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. !corrigendum 13.01(13) @drepl A representation item that is not supported by the implementation is illegal, or raises an exception at run time. @dby A representation or operational item that is not supported by the implementation is illegal, or raises an exception at run time. !corrigendum 13.01(19) @drepl For the elaboration of a @fa, any evaluable constructs within it are evaluated. @dby For the elaboration of an @fa, any evaluable constructs within it are evaluated. !corrigendum 13.03(00) @drepl Representation Attributes @dby Operational and Representation Attributes !corrigendum 13.03(01) @drepl The values of certain implementation-dependent characteristics can be obtained by interrogating appropriate representation attributes. Some of these attributes are specifiable via an @fa. @dby The values of certain implementation-dependent characteristics can be obtained by interrogating appropriate operational or representation attributes. Some of these attributes are specifiable via an @fa. !corrigendum 13.03(05) @drepl An @fa is allowed in an @fa only if this International Standard explicitly allows it, or for an implementation-defined attribute if the implementation allows it. Each specifiable attribute constitutes an aspect of representation. @dby An @fa is allowed in an @fa only if this International Standard explicitly allows it, or for an implementation-defined attribute if the implementation allows it. Each specifiable attribute constitutes an operational aspect or an aspect of representation. !corrigendum 13.03(09) @drepl The following attributes are defined: @dby The following representation attributes are defined: Address, Alignment, Size, Storage_Size, and Component_Size. !corrigendum 13.03(74) @drepl For every subtype S of a tagged type T (specific or class-wide), the following attribute is defined: @dby The following operational attribute is defined: External_Tag. For every subtype S of a tagged type T (specific or class-wide): !corrigendum 13.04(11) @drepl @xindent. For example, Pos always returns the position number, @i the internal integer code that might have been specified in a @fa.> @dby @xindent. For example, Pos always returns the position number, @i the internal integer code that might have been specified in an @fa.> !corrigendum 13.11(12) @drepl For every access subtype S, the following attributes are defined: @dby For every access subtype S, the following representation attributes are defined: !corrigendum 13.13.2(1) @drepl The Write, Read, Output, and Input attributes convert values to a stream of elements and reconstruct values from a stream. @dby The operational attributes Write, Read, Output, and Input convert values to a stream of elements and reconstruct values from a stream. !corrigendum 13.14(19) @drepl A representation item that directly specifies an aspect of an entity shall appear before the entity is frozen (see 13.1). @dby An operational item or a representation item that directly specifies an aspect of an entity shall appear before the entity is frozen (see 13.1). !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. **************************************************************** Notes from Pascal Leroy on the changes to define operational attributes, dated 2000-02-23: While there are many changes, the overall scheme is quite simple: not all attribute_definition_clauses are representation items, some are operational items. Operational items are legal in places where representation items are not (e.g. before a type is complete) but by and large they follow the same rules. One notable difference is that an implementation may decide to reject a representation item that it doesn't like, but not an operational item (with the current wording of the RM, the support of stream attributes is entirely optional, even if you support annex C). Then, for each attribute we have to say whether it's a representation attribute or an operational attribute. **************************************************************** Notes from the editor, dated 2000-03-08 Discussions with Pascal added the following points: It is quite unclear what is the scope of the sentence "The following representation attributes are defined:" in 13.3(9) (which was originally "The following attributes are defined"). Obviously it doesn't cover 13.3(61-65), which is a pragma, not an attribute. But then it seems to cover 13.3(68-73) because of the sentence that start with "For ..." in 13.3(68). At any rate, whoever wrote this part decided that there was enough confusion when reaching 13.3(74) that they specified again that "the following attribute is defined". We have changed 13.3(68) to be consistent with the idea that the scope of that statement stops at 13.3(59). But it might be clearer to change each of the attribute definitions consistently with 13.3(68) and 13.3(74), deleting 13.3(9) completely. The syntax changes are scattered about, but should not change the actual syntax of the language in any way. The reason for the syntax changes is not clear, so I'll explain it here. Ada 95 uses reference to syntax constructs wherever possible. There are several dozen uses of "Representation_Clause", many of which should not apply to operational items. In order to fix this, operational items have to be split out of Representation_Clause, which requires a syntax change. Representation_Clause is used in five places in the Ada 95 grammar (3.8, 3.11, 9.1, and 9.4 (twice). We need to consider the impact of changes in all five places. The most appealing fix is to define the syntax as follows: representation_clause ::= attribute_definition_clause | enumeration_representation_clause | record_representation_clause | at_clause operational_clause ::= attribute_definition_clause and then add operational_clause to 3.11(4) [operational attributes definition clauses only make sense in declarative parts.] However, this grammar is ambiguous, in that there is no way to tell when an attribute definition clause is operational or representational syntactically. Pascal proposed removing attribute_definition_clause from representation_clause, then adding it back where needed. He suggested only adding it to 3.11(4), as that is the primary usage. However, that would prevent the use of attribute definition clauses in protected types (both specification and body), task specifications, and component clauses. While not all of these have useful clauses today, eliminating their use in those places would be a substantial change. Randy (the editor) proposed the following: representation_clause ::= attribute_definition_clause | representation_item_clause representation_item_clause ::= enumeration_representation_clause | record_representation_clause | at_clause This has the advantage of not requiring changes at the uses of representation_clause. However, Pascal though it to be too confusing (that a representation_clause wasn't necessarily a representation clause), and I agreed with him. Therefore, I've changed the grammar to: aspect_clause ::= attribute_definition_clause | representation_clause representation_clause ::= enumeration_representation_clause | record_representation_clause | at_clause and modified all 5 uses. This version allows use to use "aspect_clause" rather than "representation_clause and attribute_definition_clause" wherever some rule applies to both representation and operational aspects. One alternative would be to avoid the syntax changes altogether by saying "representation_clauses except operational items" at the appropriate points. But that seems to confuse the issue. Note that the changes listed here don't include the corresponding changes in the (non-normative) syntax summary. I'll do this in the integrated reference manual, of course, but doing it here just bulks this up further. **************************************************************** Notes from the editor, dated 2000-04-12 AT the Phoenix ARG meeting, it was decided to minimize the syntax changes (by only changing Representation_Clause to Aspect_Clause), and make all other changes in the text. The current wording reflects that. **************************************************************** From: Pascal Leroy Sent: Friday, June 16, 2000 3:35 AM I am looking at DR 9 and I am puzzled by an inconsistency between 13.1(9) and 13.14(9) in the existing RM. These paragraphs read: "A representation item that directly specifies an aspect of a subtype or type shall appear after the type is completely defined and before the subtype or type is frozen." (13.1(9)) "A representation item that directly specifies an aspect of an entity shall appear before the entity is frozen." (13.14(19)) 13.1(9) seems to allow a representation item for a subprogram, object, etc. after it has been frozen. 13.14(19) seems to disallow such a representation item. 13.14(19) is between square brackets, so presumably it should be a consequence of other rules, but it isn't. Clearly DR 9, which rewrites these paragraphs, ought to fix the inconsistency. However, I am not sure which paragraph is correct. **************************************************************** From: Erhard Ploedereder Sent: Friday, June 16, 2000 10:36 AM I don't see the inconsistency. It's only a partial duplication, with 13.1(9) adding an additional constraint for types and subtypes (namely the "after the type is completely defined"). Now, a better way -- taken out of context -- might have been to combine the two paragraphs and say: > "A representation item that directly specifies an aspect of an entity shall > appear before the entity is frozen. In addition, a representation item > that directly specifies an aspect of a subtype or type shall appear > after the type is completely defined. ("Insufficiently wrong", I would argue or am I missing something ?) **************************************************************** From: Pascal Leroy Sent: Saturday, June 17, 2000 2:03 AM > I don't see the inconsistency. It's only a partial duplication, with 13.1(9) > adding an additional constraint for types and subtypes (namely the "after > the type is completely defined"). The thing that was bothering me is that 13.14(19) is in square brackets, and has a cross-reference to 13.1, which seems to imply that it can somehow be deduced from some rule(s) in 13.1. But obviously that's not true because the only relevant rule is 13.1(9), which only applies to types and subtypes. > "A representation item that directly specifies an aspect of an entity shall > appear before the entity is frozen. In addition, a representation item > that directly specifies an aspect of a subtype or type shall appear > after the type is completely defined. > > ("Insufficiently wrong", I would argue or am I missing something ?) Since we are rewriting 13.1(9) anyway (because of operational items) I would be tempted to include the wording that you suggest above. It is a bit confusing that you have to look at two different places to learn about the interactions between freezing rules and representation items (at least, it confused me). "Insufficiently wrong" would be a valid argument if we didn't have to rewrite this paragraph, but we do, so we might as well do it right. **************************************************************** From: Randy Brukardt Sent: Monday, June 19, 2000 5:41 PM For what its worth, we are not rewriting 13.1(9); we're only inserting a new one after it. So that particular reason for changing it doesn't hold water. We did change 13.14(19), but it isn't the problem. Additionally, there is no problem with the RM, only with the AARM. It is the @redundant for 13.14(19) that's wrong, not necessarily any of the wording. On the other hand 13.14(19.b) clearly references 13.1(7) (the *wrong* paragraph!) as the full definition, and blames^H^H^H^H^H^Hattributes the change to a WG9 resolution. One could argue that incompletely making a WG9-required change is a bug. I would be concerned about adding anything else to this AI, simply because the increases the risk that it isn't right. We're still a long ways from having any consensus on it as it is, the more stuff we stick into it, the more likely that we'll have to kill it at the meeting. **************************************************************** From: Pascal Leroy Sent: Tuesday, June 20, 2000 4:25 AM > I would be concerned about adding anything else to this AI, simply because > the increases the risk that it isn't right. We're still a long ways from > having any consensus on it as it is, the more stuff we stick into it, the > more likely that we'll have to kill it at the meeting. Ok, I withdraw my suggestion. **************************************************************** From: Randy Brukardt Sent: Monday, July 07, 2000 8:05 PM At the Potsdam meeting, we split up the giant paragraph 13.1(1) in order to improve its clarity. The first paragraph of the new text now reads: Two aspects of entities can be specified: aspects of representation and operational aspects. Representation items specify how the types and other entities of the language are to be mapped onto the underlying machine. Operational items specify other properties of entities. This has bothered me since the meeting, as it introduces 4 terms without connecting them in any way. They do eventually get connected - in paragraphs 13.1(8) and 13.1(8.1) - an entire page later! I'm wondering if we should add an informal connecting sentence. Also, shouldn't the first sentence say "Two {kinds of} aspects of entities..." Surely there are more than 2 aspects of entities?? So, here is my cut at an improvement. Representation and operational items can be used to specify aspects of entities. Two kinds of aspects of entities can be specified: aspects of representation and operational aspects. Representation items specify how the types and other entities of the language are to be mapped onto the underlying machine. Operational items specify other properties of entities Fire away with suggestions or just to tell me to leave it alone. Randy. ****************************************************************