!standard 08.03 (25) 99-05-27 AI95-00143/04 !class confirmation 98-04-01 !status WG9 approved 98-06-12 !status ARG Approved 12-0-0 98-04-01 !status received 96-06-06 !priority Medium !difficulty Easy !subject Distinct Names for Compilation Units !summary The full expanded names of the library units and subunits included in a given partition must be distinct. Thus, a partition cannot contain both a subunit and a child unit with the same name, if they have the same parent. This is a "Post-Compilation Rule", which means that it must be checked at "link time", or earlier. An implementation might allow program libraries to exist with such duplicate names, and check the rule at link time, or it might disallow such program libraries from existing in the first place. Other variations are possible. In any case, the language does not specify how to resolve such duplicate names. !question It appears that there is no way to prevent a subunit package and a child package with the same expanded names from declaring identically named subunit stubs. Furthermore, it is unclear how to resolve the parent_unit_name of a subunit when the environment contains both a library_item and a subunit having the same expanded name. !response 10.2(19) says: The full expanded names of the library units and subunits included in a given partition shall be distinct. This is a post-compilation rule. As explained in 1.1.2(29) and 1.1.5(4), post-compilation rules are detected at link time, at the latest, but an implementation may choose to detect them at compile time, instead. 1.1.2(29.a) and 1.1.5(4.a) explain this in more detail. !ACATS test ACATS tests CA20002 and LA20001 check that 10.2(19) is enforced. !appendix !section 8.3(25) !subject Ambiguity of the parent_unit_name of a subunit !reference RM95-8.3(25) !reference RM95-8.6(16) !reference RM95-10.1.1(26) !reference RM95-10.1.3(8) !reference RM95-10.1.6(4) !reference AARM95-10.1.3(24.a) !from Dan Rittersdorf 96-05-09 !keywords subunit, parent_unit_name, child library_item, ambiguity !reference 96-5545.a Dan Rittersdorf 96-5-10>> !discussion It appears that there is no way to prevent a subunit package and a child package with the same expanded names from declaring identically named subunit stubs. Furthermore, it is unclear how to resolve the parent_unit_name of a subunit when the environment contains both a library_item and a subunit having the same expanded name. RM95-10.1.3(8) states that the parent body of a subunit is the body of the program unit denoted by its parent_unit_name. The use of the defined term "denote" in this case is inappropriate, because the term is defined in RM95-8.6(16) in terms of a "denoted declaration" determined by the interpretation of the usage name. An interpretation is defined in terms of a complete context, and a subunit (much less its program_unit_name) is not a complete context. RM95-10.1.6(4) makes it clear that given a subunit and a child library item in the environment, each with the same expanded name, both are visible within the "separate (parent_unit_name)" portion of a subunit. Because a subunit does not constitute a complete context, and ambiguity is defined only for complete contexts, the parent_unit_name cannot be ambiguous, and furthermore, its "ambiguity" is not even disallowed. AARM 10.1.3(24.a) indicates that it may be intended that subunits must have distinct expanded names, but such intent doesn't seem to have been borne out by the RM. Therefore it is unclear whether or not the program unit containing the "separate (parent_unit_name)" clause is legal. If it is, it is also not apparent which of the two possible parent units is intended. Consider an example. Assume each program unit is compiled in the order given below: package foo is end foo; package foo.bar is procedure caller; end foo.bar; package body foo is package bar is function get_value return integer ; end bar; package body bar is separate ; end foo; separate(foo) package body bar is function get_value return integer is separate; end bar; separate(foo.bar) function get_value return integer is begin return 1; end get_value; -- Within the "separate (foo.bar)" portion, the foo.bar child package -- specification and the foo.bar body_stub are both visible, so the -- subunit's parent_unit_name is "ambiguous". -- If the defining_program_unit_name "get_value" can be used, it is -- possible for the compiler to determine which unit is meant by searching -- both units for a corresponding body_stub. It is not clear that such -- behavior is intended. with ada.text_io; package body foo.bar is function get_value return integer is separate ; procedure caller is begin text_io.put_line(integer'image(foo.bar.get_value)); end caller; end foo.bar; -- Note that 8.3(26) doesn't prevent the declaration of get_value in the -- foo.bar child package body, because it doesn't occur "immediately within" -- the same declarative region as the declaration in the foo.bar subunit. separate(foo.bar) function get_value return integer is begin return 2; end get_value; -- In this case, the parent_unit_name is "ambiguous", and it is unclear which -- of the body_stubs contained in the two possible meanings of foo.bar is -- intended. Assuming all prior compilation units were accepted, should -- this unit be illegal? If so, why? -- If not, how is the corresponding stub chosen? -- If the foo.bar.get_value body_stub in the child unit should be illegal, why? There doesn't appear to be enough justification in the RM for any of the above program units to be illegal, yet the final subunit cannot make sense! Furthermore, if the foo.bar child unit is compiled _after_ the first foo.bar.get_value subunit, it is not clear whether or not the subunit is still legal and/or consistent in the environment. The subunit has a semantic dependence on its parent body (from RM95-10.1.1(26)), however, the meaning of that parent body has now become "ambiguous". I would ask for the following: o A definition of "denotes" in such a way that it is clear that the parent_unit_name of a subunit must resolve to a single visible library_item or subunit. o Clarification of the consequences of homographs being visible within contexts covered by RM95-10.1.6. (i.e. what are the consequences of having multiple program units in the environment whose defining_program_unit_name matches the parent_unit_name of a subunit?) (and assuming it should be legal to compile the foo.bar subunit and foo.bar child packages both into the environment,) o Freedom to consider a previously compiled subunit inconsistent if multiple program_units exist in the environment having the same expanded name as the parent_unit_name of the subunit. -- ______________________________________________________________________________ Dan.Rittersdorf@Mail.HCSC.Com 178 Washington Street Harris Computer Systems Corporation Sparta, MI 49345-1324 Ft. Lauderdale, FL 33309 Phone: +1 (616) 887-5431 ______________________________________________________________________________ **************************************************************** !section 8.3(25) !subject Ambiguity of the parent_unit_name of a subunit !reference RM95-8.3(25) !reference RM95-8.6(16) !reference RM95-10.1.1(26) !reference RM95-10.1.3(8) !reference RM95-10.1.6(4) !reference AARM95-10.1.3(24.a) !reference 96-5545.a Dan Rittersdorf 96-05-09 !keywords subunit, parent_unit_name, child library_item, ambiguity !from Bob Duff !reference 96-5547.a Robert A Duff 96-5-10>> !discussion > It appears that there is no way to prevent a subunit package and a > child package with the same expanded names from declaring identically > named subunit stubs. Furthermore, it is unclear how to resolve the > parent_unit_name of a subunit when the environment contains both a > library_item and a subunit having the same expanded name. 10.2(19) says: The full expanded names of the library units and subunits included in a given partition shall be distinct. This is a post-compilation rule. As explained in 1.1.2(29) and 1.1.5(4), post-compilation rules are detected at link time, at the latest, but an implementation may choose to detect them at compile time, instead. 1.1.2(29.a) and 1.1.5(4.a) explain this in more detail. An implementation will probably make life easier for itself if it detects violations 10.2(19) at compile time, rather than at link time. (The RM doesn't actually talk about "link time", since there is really no requirement that there be a separate link step. The RM says, before run time. I'm using "link time" as an informal term meaning "before run time", since most implementations have a separate linking/binding step.) > RM95-10.1.3(8) states that the parent body of a subunit is the body > of the program unit denoted by its parent_unit_name. > > The use of the defined term "denote" in this case is inappropriate, > because the term is defined in RM95-8.6(16) in terms of a "denoted > declaration" determined by the interpretation of the usage name. > An interpretation is defined in terms of a complete context, and a subunit > (much less its program_unit_name) is not a complete context. Correct. The program_unit_name of a subunit should probably have been defined to be a complete context. However, most implementations won't care, since they will forbid, at compile time, duplicate names. > RM95-10.1.6(4) makes it clear that given a subunit and a child library item > in the environment, each with the same expanded name, both are visible within > the "separate (parent_unit_name)" portion of a subunit. Because a subunit > does not constitute a complete context, and ambiguity is defined only for > complete contexts, the parent_unit_name cannot be ambiguous, and furthermore, > its "ambiguity" is not even disallowed. > > AARM 10.1.3(24.a) indicates that it may be intended that subunits must have > distinct expanded names, but such intent doesn't seem to have been borne > out by the RM. This is implied by 10.2(19). Note that 10.1.3(14) requires *some* of these cases to be detected at compile time, but that's not the case you're worrying about. > Therefore it is unclear whether or not the program unit containing the > "separate (parent_unit_name)" clause is legal. If it is, it is also not > apparent which of the two possible parent units is intended. > > > Consider an example. Assume each program unit is compiled in the order > given below: OK, but note that the notion of compiling things in a certain order is an Ada 83 notion. The RM allows this model, but does not require it. For example, an implementation might not provide any command for compiling a given unit or source file -- it might just provide a "bring everything up to date" command, which might figure out what order to compile things in and/or might compile things in parallel. Such an implementation is valid. > package foo is > end foo; > > package foo.bar is > procedure caller; > end foo.bar; > > package body foo is > package bar is > function get_value return integer ; > end bar; > > package body bar is separate ; > end foo; An implementation is allowed, but not required to give an error message at this point, based on 10.2(19). > separate(foo) > package body bar is > function get_value return integer is separate; > end bar; If it didn't complain above, it can complain now. > separate(foo.bar) > function get_value return integer is > begin > return 1; > end get_value; > > -- Within the "separate (foo.bar)" portion, the foo.bar child package > -- specification and the foo.bar body_stub are both visible, so the > -- subunit's parent_unit_name is "ambiguous". If the compiler allowed things to get this far, then it can presumably complain about 10.2(19) now. But I agree that the parent unit name should be considered a complete context, and therefore ambiguous. > -- If the defining_program_unit_name "get_value" can be used, it is > -- possible for the compiler to determine which unit is meant by searching > -- both units for a corresponding body_stub. It is not clear that such > -- behavior is intended. Well, it certainly shouldn't be *required*. If it is allowed, then the program is going to get an error at link time anyway. > with ada.text_io; > package body foo.bar is > function get_value return integer is separate ; > > procedure caller is > begin > text_io.put_line(integer'image(foo.bar.get_value)); > end caller; > end foo.bar; Note that compilers don't necessarily have to detect these errors and give error messages -- instead, a compiler can simply prevent the problem from occurring in the first place. For example, GNAT requires the two bodies called "foo.bar" to be in a file called "foo-bar.adb", and you can't have two files with the same name, so you couldn't create this example, in GNAT, in the first place. GNAT is certainly a valid implementation in this respect. See 10.1.4(7). > -- Note that 8.3(26) doesn't prevent the declaration of get_value in the > -- foo.bar child package body, because it doesn't occur "immediately within" > -- the same declarative region as the declaration in the foo.bar subunit. Right. But 8.3(26) isn't really relevant in any case -- it prevents homographs, whereas the separate compilation rules are intended to prevent two separately compiled things with the same name, whether or not they are homographs. > separate(foo.bar) > function get_value return integer is > begin > return 2; > end get_value; > > -- In this case, the parent_unit_name is "ambiguous", and it is unclear which > -- of the body_stubs contained in the two possible meanings of foo.bar is > -- intended. Assuming all prior compilation units were accepted, should > -- this unit be illegal? If so, why? 10.2(19) says this is illegal at link time. It would be smarter, IMHO, for the implementation to detect the problem earlier. > -- If not, how is the corresponding stub chosen? > > -- If the foo.bar.get_value body_stub in the child unit should be illegal, why? > > > There doesn't appear to be enough justification in the RM for any of the above > program units to be illegal, yet the final subunit cannot make sense! > > Furthermore, if the foo.bar child unit is compiled _after_ the first > foo.bar.get_value subunit, it is not clear whether or not the subunit is > still legal and/or consistent in the environment. The subunit has a semantic > dependence on its parent body (from RM95-10.1.1(26)), however, the meaning > of that parent body has now become "ambiguous". This is up to the implementation. The RM doesn't really care which is compiled "after" the other. > I would ask for the following: > > o A definition of "denotes" in such a way that it is clear that the > parent_unit_name of a subunit must resolve to a single visible > library_item or subunit. Agreed. The parent_unit_name of a subunit should be considered a complete context. > o Clarification of the consequences of homographs being visible within > contexts covered by RM95-10.1.6. (i.e. what are the consequences of > having multiple program units in the environment whose > defining_program_unit_name matches the parent_unit_name of a subunit?) Illegal at link time, and *may* be illegal at compile time. > (and assuming it should be legal to compile the foo.bar subunit and foo.bar > child packages both into the environment,) > > o Freedom to consider a previously compiled subunit inconsistent if > multiple program_units exist in the environment having the same expanded > name as the parent_unit_name of the subunit. This is certainly true. It's up to the implementation to decide whether to detect this at link time or compile time. - Bob **************************************************************** !section 10.2(19) !subject Ambiguity of the parent_unit_name of a subunit !reference 96-5545.a Dan Rittersdorf 96-05-09 !reference 96-5547.a Bob Duff 96-05-10 !keywords subunit, parent_unit_name, child library_item, ambiguity !from Dan Rittersdorf !reference 96-5549.a Dan Rittersdorf 96-5-10>> !discussion Bob, > > It appears that there is no way to prevent a subunit package and a > > child package with the same expanded names from declaring identically > > named subunit stubs. Furthermore, it is unclear how to resolve the > > parent_unit_name of a subunit when the environment contains both a > > library_item and a subunit having the same expanded name. > > 10.2(19) says: > > The full expanded names of the library units and subunits included > in a given partition shall be distinct. > > This is a post-compilation rule. As explained in 1.1.2(29) and > 1.1.5(4), post-compilation rules are detected at link time, at the > latest, but an implementation may choose to detect them at compile time, > instead. > > 1.1.2(29.a) and 1.1.5(4.a) explain this in more detail. > > An implementation will probably make life easier for itself if it > detects violations 10.2(19) at compile time, rather than at link time. > While we were looking for a compile-time rule, this is a bit helpful. We disagree slightly with some of your comments below, however. > > > RM95-10.1.3(8) states that the parent body of a subunit is the body > > of the program unit denoted by its parent_unit_name. > > > > The use of the defined term "denote" in this case is inappropriate, > > because the term is defined in RM95-8.6(16) in terms of a "denoted > > declaration" determined by the interpretation of the usage name. > > An interpretation is defined in terms of a complete context, and a subunit > > (much less its program_unit_name) is not a complete context. > > Correct. The program_unit_name of a subunit should probably have been > defined to be a complete context. However, most implementations won't > care, since they will forbid, at compile time, duplicate names. > It is not clear that there is sufficient grounds to do this *at compile time* in all cases. See below. > > > > Consider an example. Assume each program unit is compiled in the order > > given below: > > OK, but note that the notion of compiling things in a certain order is > an Ada 83 notion. The RM allows this model, but does not require it. > For example, an implementation might not provide any command for > compiling a given unit or source file -- it might just provide a "bring > everything up to date" command, which might figure out what order to > compile things in and/or might compile things in parallel. Such an > implementation is valid. > Granted, the problem still manifests itself, regardless of compilation order. > > package foo is > > end foo; > > > > package foo.bar is > > procedure caller; > > end foo.bar; > > > > package body foo is > > package bar is > > function get_value return integer ; > > end bar; > > > > package body bar is separate ; > > end foo; > > An implementation is allowed, but not required to give an error message > at this point, based on 10.2(19). > Here we disagree. It is not clear that an error message is allowed based upon 10.2(19), because that rule is regarding multiple library items and subunits with the same full expanded name in the same partition. It is not clear (and may well be incorrect to assume), when compiling the subunit that the child library unit having the same expanded name will be required in any partition. If the child unit is never used to create a program, then it seems imcorrect to issue an error message for the subunit on the grounds of 10.2(19). > > separate(foo) > > package body bar is > > function get_value return integer is separate; > > end bar; > > If it didn't complain above, it can complain now. > Again, it is not clear that it can be correct to issue an error message on the grounds of 10.2(19). > > separate(foo.bar) > > function get_value return integer is > > begin > > return 1; > > end get_value; > > > > -- Within the "separate (foo.bar)" portion, the foo.bar child package > > -- specification and the foo.bar body_stub are both visible, so the > > -- subunit's parent_unit_name is "ambiguous". > > If the compiler allowed things to get this far, then it can presumably > complain about 10.2(19) now. But I agree that the parent unit name > should be considered a complete context, and therefore ambiguous. > Is it possible to obtain (what used to be called) a binding interpretation stating that the parent_unit_name of a subunit is a complete context? > > -- If the defining_program_unit_name "get_value" can be used, it is > > -- possible for the compiler to determine which unit is meant by searching > > -- both units for a corresponding body_stub. It is not clear that such > > -- behavior is intended. > > Well, it certainly shouldn't be *required*. If it is allowed, then the > program is going to get an error at link time anyway. > Only is the child unit is required by the partition. This may be significant. > > with ada.text_io; > > package body foo.bar is > > function get_value return integer is separate ; > > > > procedure caller is > > begin > > text_io.put_line(integer'image(foo.bar.get_value)); > > end caller; > > end foo.bar; > Note that this is the first place it would seem reasonable to detect the foo.bar subunit in the environment and issue an error message based upon 10.2(19). If the child unit is linked in a partition, then clearly the foo.bar subunit would be required. The converse is certainly not true. > Note that compilers don't necessarily have to detect these errors and > give error messages -- instead, a compiler can simply prevent the > problem from occurring in the first place. For example, GNAT requires > the two bodies called "foo.bar" to be in a file called "foo-bar.adb", > and you can't have two files with the same name, so you couldn't create > this example, in GNAT, in the first place. GNAT is certainly a valid > implementation in this respect. See 10.1.4(7). > It is not clear that 10.1.4(7) gives this degreee of freedom at all. 10.1.4(7) states that a library_item (not a subunit) may be replaced if another library_item with the same defining_program_unit_name is added. It doesn't give permission for the removal of a subunit with the same expanded name when adding a library_item. In fact, a subunit has no defining_unit_name that can match that of a child unit, as the parent_unit_name is not part of a subunit's defining_program_unit_name. 10.1.4(7) also gives permission to replace a "preexisting version of the same compilation unit" when a subunit or library unit body is added to the environment. It is not clear that "version of the same compilation unit" can be stretched so far as to refer to a library_item body having the same expanded_name as a subunit or vice versa. If there were a binding interpretation to this extent, then I would agree that GNAT has legitimately taken advantage of 10.1.4(7). It would be beneficial to us to take advantage of it as well in this case. Can an implementation define what constitutes a version "of the same compilation unit"? > > separate(foo.bar) > > function get_value return integer is > > begin > > return 2; > > end get_value; > > > > -- In this case, the parent_unit_name is "ambiguous", and it is unclear which > > -- of the body_stubs contained in the two possible meanings of foo.bar is > > -- intended. Assuming all prior compilation units were accepted, should > > -- this unit be illegal? If so, why? > > 10.2(19) says this is illegal at link time. It would be smarter, IMHO, > for the implementation to detect the problem earlier. > Certainly at this point, if the foo.bar subunit can be detected in the environment, it is reasonable to issue an error message on the grounds of 10.2(19), as both program units *would* be required of any partition which includes the child unit. -- ______________________________________________________________________________ Dan.Rittersdorf@Mail.HCSC.Com 178 Washington Street Harris Computer Systems Corporation Sparta, MI 49345-1324 Ft. Lauderdale, FL 33309 Phone: +1 (616) 887-5431 ______________________________________________________________________________ ****************************************************************