The prefix of an expanded name AI-00119/09 1 93-06-24 BI WA | !standard 04.01.03 (18) 93-06-24 AI-00119/09 !standard 04.01.03 (17) !standard 04.01.03 (19) !standard 08.07 (13) !class binding interpretation 88-03-28 | !status WG9-approved 93-06-18 !status ARG-approved 93-03-25 (reviewed) !status ARG-approved 90-09-14 (11-0-0) (pending editorial review) !status work-item 90-06-15 !status WG9 returned to ARG 90-06-15 !status ARG-approved 89-10-25 (reviewed) !status ARG-approved (10-0-0) 89-06-14 (pending editorial review) !status work-item 88-03-28 (returned to committee by Chair) !status panel/committee-approved (6-0-2) 87-02-18 (pending letter ballot) !status work-item 86-08-05 !status received 83-11-07 !references AI-00016, AI-00187, 83-00171, 83-00812, 83-00924 !topic The prefix of an expanded name !SUMMARY 93-03-25 When deciding whether the prefix of a selected component is the name of an enclosing subprogram or accept statement (and hence, whether the selected component is an expanded name), no names declared by renaming declarations are considered. !QUESTION 89-07-28 4.1.3(19) says: If, according to the visibility rules, there is at least one possible interpretation of the prefix of a selected component as the name of an enclosing subprogram or accept statement, then the only interpretations considered are those of rule (f), as expanded names (no interpretations of the prefix as a function call are then considered). Does the term "the name of" include names declared by renaming declarations? 3.1(6) defines the term "name of:" Several forms of declaration associate an identifier with a declared entity. Within its scope, and only there, there are places where it is possible to use the identifier to refer to the associated declared entity; these places are defined by the visibility rules (see 8.3). At such places the identifier is said to be a NAME of the entity (its simple name); the name is said to DENOTE the associated entity. This paragraph says that an identifier is A NAME OF the entity that it denotes. In particular, a name declared by a renaming declaration is a name of the entity it denotes. When 4.1.3(19) speaks of THE name of an enclosing subprogram or accept statement, does it mean to exclude names declared by renaming declarations? Consider G.X in the following example. The prefix of an expanded name AI-00119/09 2 93-06-24 BI WA -- Example 1 type REC is record X : INTEGER; end record; function H return REC; function G return REC renames H; function H return REC is Y : INTEGER; begin Y := G.X; -- illegal? (no; is legal) ... end H; Is G "the" name of subprogram H? If so, G.X is illegal since 4.1.3(18) prohibits the use of a name declared by a renaming declaration as the prefix of an expanded name. Alternatively, the rule in 4.1.3(19) excludes names declared by renaming declarations as prefixes of expanded names (since 4.1.3(18) does not allow them) and considers "the" name of a subprogram (or accept statement) to be the name used in the subprogram's (or entry's) declaration. With this understanding, G.X is not considered an expanded name, so G is considered as a function call. Such a call is legal since the called function returns a value that has a component denoted by X. Hence, we have the following question: 1. If the prefix of a selected component is a name declared by a renaming declaration, can this name be considered to be "the name of an enclosing subprogram or accept statement" for the purpose of deciding whether the selected component is an expanded name? Now let's consider a case where the selected component is clearly an expanded name and where the prefix denotes more than one enclosing subprogram: -- Example 2 procedure H; procedure J renames H; procedure H is X : INTEGER := 0; The prefix of an expanded name AI-00119/09 3 93-06-24 BI WA function J return FLOAT is X : FLOAT; begin J.X := 1.0; -- (1) illegal? (no) ... end J; begin ... end H; For expanded names whose selector is declared (see AI-00187) immediately within an enclosing construct, 4.1.3(18) says: This form [(f)] of expanded name is only allowed within the construct itself (including the body and any subunits, in the case of a program unit). A name declared by a renaming declaration is not allowed as the prefix. If the prefix is the name of a subprogram or accept statement and if there is more than one visible enclosing subprogram or accept statement of this name, the expanded name is ambiguous, independently of the selector. Because of the renaming declaration, J at (1) is a NAME OF both the enclosing function and the enclosing procedure. Does this mean J.X is ambiguous and hence, illegal? Alternatively, since a name declared by a renaming declaration cannot be a prefix of an expanded name, shouldn't J be considered to be "THE name of" only one "visible enclosing subprogram or accept statement?" If so, J in J.X is unambiguous, and J.X is legal. Hence, we have the following question: 2. If the prefix of a selected component is a name declared by a renaming declaration, is the denoted subprogram considered when deciding whether there is more than one visible enclosing subprogram or accept statement "of this name?" A similar example can be constructed for nested accept statements. !RECOMMENDATION 90-07-06 If, according to the visibility rules, a possible meaning of the prefix of a selected component is given by an entry declaration, a subprogram declaration, or a subprogram body, and the selected component occurs within an accept statement for that entry or within the subprogram body for that subprogram, then the selected component is interpreted as an expanded name (no interpretations of the prefix as a function call or as a name declared by a renaming declaration are then considered). Moreover, if there is more than one such enclosing accept statement or subprogram body, the expanded name is ambiguous, independently of the selector. The prefix of an expanded name of the second form (4.1.3(f)) must be associated by the visibility rules with the declaration of a program unit, the name of a block statement, the name of a loop statement, or an entry declaration (but not a renaming declaration). In the case of an entry declaration, the prefix must be either the simple name of the entry or entry The prefix of an expanded name AI-00119/09 4 93-06-24 BI WA family, or an expanded name ending with such a simple name (that is, no index is allowed). The selector must be a simple name, character literal, or operator symbol declared (see AI-00187) immediately within the construct denoted by the prefix. This form of expanded name is only allowed within the construct denoted by the prefix (including the body and any subunits, in the case of a program unit) or, in the case of an entry, within an accept statement for that entry. !DISCUSSION 90-12-22 The recommendation says, in essence, that when deciding whether the prefix of a selected component is the name of an enclosing subprogram or accept statement, no names declared by renaming declarations are considered. G.X in Example 1 is not an expanded name because G is not associated with a subprogram declaration by the visibility rules; it is associated with a 1 renaming declaration. Interpretations other than an expanded name are then considered. In particular, G can be interpreted as a function call. Such a function call can return a record having component X, so G.X is not illegal. In short, the answer to question (1) is "No." As for Example 2, the recommendation says, in essence, that when deciding whether there is more than one visible enclosing subprogram or accept statement whose name is given by the prefix of a selected component, no names declared by renaming declarations are considered. Hence, J.X in Example 2 is legal. The complete reasoning implied by the recommendation is this: According to the visibility rules, a possible meaning of J is given by a subprogram body. Since J.X occurs within this body, J.X must be considered an expanded name. Since there is only one enclosing subprogram body (or accept statement) associated with J by the visibility rules, J.X is considered an unambiguous expanded name. Since X is declared immediately within the enclosing J, J.X is a legal expanded name. Essentially the same reasoning applies when the enclosing constructs are accept statements. So the answer to question (2) is also "No." The recommendation and the above reasoning reflect the intent of the design. In the 1980 version of Ada, function calls with no parameters were written with empty parentheses. With this notation F().X meant that function F was invoked and component X was selected from the result, whereas F.X selected _______________ 1 The recommendation implicitly forbids the use of a name declared by a renaming declaration as a prefix of an expanded name of the second form by failing to list "renaming declaration" as one of the constructs associated with a prefix by the VISIBILITY rules. In Example 1, the visibility rules do not associate G with the denoted subprogram, but instead associate identifier G with a renaming declaration, which is not one of the constructs allowed as a prefix of an expanded name by the recommendation. The prefix of an expanded name AI-00119/09 5 93-06-24 BI WA declaration X within function F. In the revised (and current) version, parameterless function calls do not use empty parentheses, so the name F.X is potentially ambiguous -- under certain conditions, F.X can be considered either an expanded name or the selection of component X from the result of calling function F. The current rules in the Standard deal with the various ways in which this ambiguity can arise. First, the rule in 4.1.3(19) is intended to give a preference to an interpretation as an expanded name. The motivation for this rule is indicated by the following example: type REC is record T : INTEGER; end; function F return REC is subtype T is INTEGER; X : F.T := F.T; -- illegal begin ... end F; Even though F is not overloaded, the name F.T has multiple interpretations. The use of F.T in X's declaration with two different interpretations was not considered helpful, either to readers or to implementers, so 4.1.3(19) specifies that if F.T can be interpreted as an expanded name, only that interpretation is the one considered; the second occurrence of F.T is illegal. The preference rule in paragraph 19 is not, however, sufficient to avoid all such problems: function F return FLOAT is subtype T is INTEGER; procedure F is T : INTEGER := 1; X : F.T := F.T; -- illegal begin ... end F; begin ... end F; Here a kind of overloading resolution is needed to resolve the interpretations of F.T, even though F.T is an expanded name in both of its occurrences. To avoid this complexity of interpretation (both for implementers and for those reading the program), the rule in 4.1.3(18) makes such occurrences illegal, even when there is no possible ambiguity. Renaming declarations can introduce similar problems, e.g.: The prefix of an expanded name AI-00119/09 6 93-06-24 BI WA function F return FLOAT is subtype T is INTEGER; procedure G is procedure F renames G; T : INTEGER := 1; X : F.T := F.T; -- illegal begin ... end G; begin ... end F; The renaming declaration creates the problem that existed in the previous example. In the July 1982 draft of the Standard, this use of renaming declarations was prohibited by forbidding a renaming declaration that renames an enclosing program unit. But David Taffs pointed out (in comment #5135) that the same problem could arise when a renaming declaration was given outside the renamed unit. For example: function H return FLOAT; function F return FLOAT renames H; function H return FLOAT is subtype T is INTEGER; procedure F is T : INTEGER := 1; X : F.T := F.T; -- illegal begin ... end F; begin ... end H; When this was pointed out, the rule forbidding the renaming of enclosing units was removed in favor of the current rule disallowing the use of a name declared by a renaming declaration as the prefix of an expanded name of the second form (f). Another unusual and undesirable use of names declared by renaming declarations was also disallowed by this rule: procedure PROC; package P is procedure F renames PROC; end P; procedure PROC is subtype T is INTEGER; procedure F is T : INTEGER := 1; X : P.F.T := F.T; -- illegal begin ... end F; begin ... end F; P.F.T could be considered an expanded name, since each prefix denotes an enclosing program unit (i.e., P encloses the declaration of F, and the unit denoted by F encloses a declaration of T), but not all units denoted by the The prefix of an expanded name AI-00119/09 7 93-06-24 BI WA prefixes in this name are declarations of visible BODIES enclosing T's declaration, so P.F.T does not really fit the intended notion of an expanded name, and is forbidden. In stating the rules in 4.1.3(17-19) that forbid these examples, the term "name of" was used with the understanding that names declared by renaming declarations were not allowed as prefixes. The recommendation states the intended effect more clearly. The original question that led to this commentary was this: function F return T1 is -- F1 X : INTEGER; function G return T2 is X : INTEGER; function F return T2 renames G; -- F2 begin F.X := 0; -- legal? (yes) end G; begin ... end F; We can now analyze this example in light of the recommendation. Suppose types T1 and T2 are different, so both F1 and F2 are visible. Paragraph 8.7(2) specifies that the visibility rules should be used first to determine possible acceptable meanings of F in the selected component F.X, and only later, in the case that more than one such meaning has been determined, is overload resolution to be invoked. The visibility rules show that both declarations of F are directly visible at the place of the selected component, on the assumption that T1 and T2 are different types. Now the overloading resolution rule 8.7(13) specifies that section 4.1.3(17-18) is to be considered, and the effect of the recommendation is to exclude the renaming declaration as a possible interpretation of F. Consequently, the selected component is interpreted as an expanded name, F1 is determined as the actual meaning of the given prefix, and the example is legal. Now suppose that T1 and T2 denote the same type. In this case, by 8.3(15), the two declarations for F are homographs. F.X is within the immediate scope of the renaming declaration, so the outer declaration is hidden. F2 is left as the only possible meaning for the prefix under the visibility rules. The overloading rules are not invoked. Since F2 is a renaming declaration, F.X is not interpreted as an expanded name, i.e., F is interpreted as a function call. The selected component is legal if T2 is an access type and the designated type has a component named X.