Forcing occurrences for component types AI-00494/02 1 87-01-16 BI WI | !standard 13.01 (06) 87-01-16 AI-00494/02 !class binding interpretation 87-01-16 (provisional classification) !status work-item 87-01-16 !status received 86-11-10 !topic Forcing occurrences for component types !summary 87-01-16 (DRAFT) The occurrence of a representation clause for a composite type does not force determination of the default representation of the subcomponent types. !question 87-01-16 (DRAFT) 13.1(6) says: Certain occurrences [of a type name] imply that the repre- sentation of the type must already have been determined. ... This default determination is also forced by similar occurrences of the name of a subtype of the type, or of the name of any type or subtype that has subcomponents of the type. A forcing occurrence is any occurrence other than in a type or subtype declaration, a subprogram specification, an entry declaration, a deferred constant declaration, a pragma, or a representation clause for the type itself. Now consider this example: type T is range 0..15; type TT is array (1..5) of T; for TT'SIZE use ...; -- forces representation of T? (no) for T'SIZE use ...; -- legal? (yes) Since TT has a component of type T, and since the representation clause for TT is not a representation clause for T, the use of TT in its own representation clause appears to be a forcing occurrence for T. Was it intended that the occurrence of TT in its representation clause be considered a forcing occurrence for each of TT's subcomponent types? !recommendation 87-01-16 (DRAFT) The occurrence of a representation clause for a composite type is not a forcing occurrence for any of the subcomponent types. !discussion 87-01-16 (DRAFT) It was not intended that the occurrence of a representation clause for a composite type be considered to force the representation of the subcomponent types. DRAFT DRAFT DRAFT Forcing occurrences for component types AI-00494/02 2 87-01-16 BI WI | !appendix 88-04-15 ***************************************************************************** !section 13.01 (06) Ron Brender 86-10-14 83-00841 !version 1983 !topic Non-forcing for TT should not force T? The following is stimulated by the Implementors Guide, IG13 G1, Section 13.1.b/S5. See also IG 13.1.b/S1f and 13.1.b/R1f. Consider the example given in S5 (as edited from S4): type T is range 0..15; type TT is array (1..5) of T; for TT'SIZE use ...; -- Forces representation of T? for T'SIZE use ...; -- Legal? The notion that the representation clause for type TT is a forcing occurrence for type T seems totally unmotivated by the reasons for the forcing occurence concept as well as unmotivated by the text of LRM 13.1(6). It appears that the conclusion given here turns on the reading of "a representation clause FOR THE TYPE ITSELF" [emphasis added]. I have always read the emphasized phrase as a rather gratuitous bit of English redundancy, having no particular import. But I can see (after repeated readings) how it can be construed as implying that a representation clause for a type does not force the representation of that type but may still be a forcing occurrence for other types through the operation of third sentence of this paragraph. This latter interpretation seems most tenuous, however. While the above example might seem like no big deal either way (the programmer can easily reverse the order of the representation clauses), this example shows that there are more significant implications: package OUTER is type PRIV is private; package INNER is type ARR is array (1..2) of PRIV; for ARR'SIZE use 16; -- Legal? end; private type PRIV is range 0..10; DRAFT DRAFT DRAFT Forcing occurrences for component types AI-00494/02 3 87-01-16 BI WI end; According to the IG interpretation, the representation clause for ARR should be a forcing occurence for the component type PRIV. Indeed, this even seems to be supported by LRM 7.4.1(4), which fails to mention a representation clause (or a pragma) as an allowed use of a name of a private type prior to its full type declaration. However, it is not clear whether this omission is intended or an oversight (based on my personal involvement in the formation of these rules [the Brosgol anomoly again!]). If the IG interpretation stands, and 7.4.1(4) is taken at face value, then it appears that there is simply no possible way to give a representation clause for type ARR. Or, even a pragma PACK! This seems like a significant limitation. LMP/LMC clarification is sought. | ***************************************************************************** | | !section 13.01 (05) David B. Kinder, Intel 88-02-24 83-00961 | !version 1983 | !topic Representation Clause causing component packing | | A representation clause (or pragma) used to determine the mapping of a | type, may be required before this type can be used as a component within a | type with an applied representation clause (or pragma). | | Discussion: | | Consider this code fragment: | | TYPE STATE IS (A, M, W, P); | TYPE STATE_MASK IS ARRAY (STATE) OF BOOLEAN; | | TYPE STATUS_WORD IS | RECORD | MACHINE_STATE : STATE_MASK; | END RECORD; | | FOR STATUS_WORD USE | RECORD AT MOD 8; | MACHINE_STATE AT 0 RANGE 12 .. 15; | END RECORD; | | S: STATE_MASK; | | Since there is no representation clause for the type STATE_MASK, the | compiler is free to determine its representation [LRM 13.1(5)]. | Furthermore, given that the field MACHINE_STATE and the variable S are of | the same type, one would demand their representations to be identical. But | for this to be true, the representation of type STATE_MASK must be as a DRAFT DRAFT DRAFT Forcing occurrences for component types AI-00494/02 4 87-01-16 BI WI | packed 4-bit array (as required by the component clause on field | MACHINE_STATE). It follows then that the component clause forces a default | representation of the type MACHINE_STATE and that all instances of type | STATE_MASK must be represented as a packed 4-bit array. | | However, AI-494 concludes that "the occurrence of a representation clause | for a composite type does not force determination of the default | representation of the subcomponent types". So we have a problem. | | If the component clause is not a forcing occurrence, then the | representation of the field MACHINE_STATE and the variable S could be | different. If it is a forcing occurrence, then the analysis of AI-494 is | wrong. | | We believe that analysis in AI-494 is correct. Furthermore, the component | clause on MACHINE_STATE could be rejected on the grounds that not enough | storage space has been provided for every allowable value of the component | [LRM 13.4(7)]. | | If the declaration of variable S were moved before the declaration of the | record STATUS_WORD, then the component clause can clearly be rejected if | the representation forced by the variable declaration is not a packed 4-bit | array. | | This example can easily be made legal however, simply by specifying a | representation clause on the array type STATE_MASK itself: | | TYPE STATE_MASK IS ARRAY (STATE) OF BOOLEAN; | FOR STATE_MASK'SIZE USE 4; | | | ***************************************************************************** | | !section 13.04 (05) David B. Kinder, Intel 88-04-15 83-00966 | !version 1983 | !topic Component clause affecting component representation | | Can a component clause affect the representation of the components type? | | Consider this example (derived from A39005G.DEP and LRM 13.4(9)): | | TYPE STATE IS (A, M, W, P); | TYPE STATE_MASK IS ARRAY (STATE) OF BOOLEAN; | | TYPE STATUS_WORD IS | RECORD | MACHINE_STATE : STATE_MASK; | END RECORD; | | FOR STATUS_WORD USE | RECORD AT MOD 8; | MACHINE_STATE AT 0 RANGE 12 .. 15; | END RECORD; DRAFT DRAFT DRAFT Forcing occurrences for component types AI-00494/02 5 87-01-16 BI WI | Since there is no representation clause for the type STATE_MASK, the | compiler is free to determine its representation [LRM 13.1(5)] -- for | example an implementation may select a representation as an array of 4 | bytes. As discussed in AI-494, "the occurrence of a representation clause | for a composite type does not force determination of the default | representation of the subcomponent types." In particular, the component | clause on the field MACHINE_STATE does not effect the representation of | other objects of type STATE_MASK. | | LRM 13.4(5) states that a "component clause specifies the storage place of | a component" -- it does not say that a component clause may affect the | representation of that component's type. Allowing this component clause | would also imply that objects of the same type could have different | representations -- a variable of type STATE_MASK might be allocated 4 | bytes, while the field MACHINE_STATE (also of type STATE_MASK) would be | allocated 4 bits. | | We believe the Standard requires objects of the same type to have the same | representation. This becomes particularly evident if we continue the | example. Now consider an assignment to a variable of this record type: | | DECLARE | S: STATUS_WORD; | MASK: STATE_MASK := STATE_MASK'(OTHERS => TRUE); | BEGIN | S.MACHINE_STATE := STATE_MASK'(OTHERS => TRUE); | S.MACHINE_STATE := MASK; | END; | | Let's assume for a moment that the component clause on MACHINE_STATE were | allowed, and so the representation of the field MACHINE_STATE would be a | packed array of 4 bits. | | Since there is no representation clause given for the type STATE_MASK, the | aggregate STATE_MASK'(OTHERS => TRUE) and the variable MASK use the default | representation of STATE_MASK (an unpacked array). But since the | representation of the field MACHINE_STATE is as a packed array, an implicit | conversion from the packed to unpacked array representation is required. | | This implicit conversion is not permitted by the Standard. In LRM 4.6(15) | it says, "Apart from the explicit type conversions, the only allowed form | of type conversion is the implicit conversion of a value of the type | universal_integer or universal_real into another numeric type." | | LRM 13.6 discusses that a change of representation must be accomplished | with explicit type conversion. An alternate representation is accomplished | by declaring a second type, derived from the first, and specifying a | different representation for the second type. Our example does not declare | a derived type so an explicit type conversion cannot be done to effect a | representation change, since there is no derived type declared. | | Some implementations may allow this example because their default | representation of arrays of boolean is a packed array (and hence the DRAFT DRAFT DRAFT Forcing occurrences for component types AI-00494/02 6 87-01-16 BI WI | component clause has no effect). In fact, we believe the LRM has | encouraged this default representation by using examples that assume this | representation is the default (see LRM 3.6(11) and LRM 13.4(9)). We | believe a representation clause for the array type STATE_MASK itself is | required to make this example (and the sited LRM examples) valid. DRAFT DRAFT DRAFT