Marc.Graham@SEI.CMU.EDU (09/25/90)
The following Ada code compiles cleanly and produces the output "Inner". Question: Is there any way that the outer outer_constant may be named from the inner testnames? If no, then why is 4.1.3 rule f (in particular, para 18 and 19) worded the way it is? (Note: if the outer testnames were a procedure, rather than a package, the expanded name testnames.outer_context is illegal within the inner testnames.) ------------------------------------------------------------ package testnames is procedure testnames (outer_constant : integer); end testnames; with text_io; use text_io; package body testnames is outer_constant : constant := 3.14159; procedure testnames (outer_constant : integer) is begin if testnames.outer_constant > 2 then put_line("Outer!"); else put_line("Inner"); end if; end testnames; end testnames; with testnames; procedure exectest is begin testnames.testnames(1); end exectest; ------------------------------------------------------------ Marc H. Graham Software Engineering Institute marc@sei.cmu.edu Carnegie Mellon University (412) 268 7784 Pittsburgh, PA 15213
dik@cwi.nl (Dik T. Winter) (09/25/90)
In article <9009241814.AA08734@bx.sei.cmu.edu> Marc.Graham@SEI.CMU.EDU writes: > > Question: Is there any way that the outer outer_constant may > be named from the inner testnames? Yes: > .... First, to prevent a semantic error, change > outer_constant : constant := 3.14159; to outer_constant : constant := 4; and next > if testnames.outer_constant > 2 then to if standard.testnames.outer_constant > 2 then -- dik t. winter, cwi, amsterdam, nederland dik@cwi.nl
NCOHEN@IBM.COM ("Norman H. Cohen") (09/26/90)
Marc Graham presents a library package TESTNAMES with the following body: package body testnames is outer_constant : constant := 3.14159; procedure testnames (outer_constant : integer) is begin ... testnames.outer_constant ... end testnames; end testnames; He observes that the occurrence of "testnames.outer_constant" in the procedure body refers to the formal parameter, not the named number, and asks whether there is any way to denote the named number from within the procedure body. Since all library units are considered to be declared directly within package STANDARD, the name STANDARD.TESTNAMES.OUTER_CONSTANT will work. (See the notes in RM 8.6(3) and 10.1(10).) Marc also asserts that if the outer TESTNAMES were a procedure rather than a package, the expanded name TESTNAMES.OUTER_CONTEXT would be illegal within the inner TESTNAMES, citing RM 4.1.3(18): If the prefix is the name of a subprogram or accept statement and there is more than one visible enclosing subprogram or accept statement of this name, the expanded name is ambiguous, independently of the selector. The key word here is VISIBLE. Marc's original example works as it does because the inner declaration of TESTNAMES hides the outer declaration throughout the immediate scope of the inner declaration (see 8.3(15)). (Marc declares the TESTNAMES procedure within the TESTNAMES package declaration, not shown above, so the package name is hidden from there through the rest of the package declaration, as well as throughout the package body.) In the case of subprograms and accept statements, overloading rules allow both an inner and an outer declaration of the same name to be visible--if the parameter and result type profiles are different. Thus a special rule is provided. (The alternative would have been to use the innermost enclosing unit, but then 4.1.3(f) could not have been phrased in terms of visibility rules. Simplicity of presentation was apparently chosen over uniform semantics for naming enclosing units in prefixes, but the issue only arises in pathological programs anyway.) Here is a (suitably pathological) illustration: procedure P (X: in Integer) is --P#1 procedure P (X: in Float) is --P#2 -- Both P#1 and P#2 visible here since profiles are different ... P.X ... -- Illegal by RM 4.1.3(18) end P; procedure P (X: in Integer) is --P#3 -- P#1 is hidden by P#3 here. ... P.X ... -- Legal, refers to formal parameter of P#3. end P; end P; Finally, Marc asks about RM 4.1.3(19), which concerns a completely different pathology: If F is a parameterless function returning a record value with component C, then within a unit named F, the name F.C could be interpreted either as a call on the function followed by selection of the record component (which 4.1.3(19) explicitly excludes) or as the name of an entity C declared immediately within unit F.
eachus@linus.mitre.org (Robert I. Eachus) (10/02/90)
Of course if you replace the name testnames with STANDARD, now it is impossible to name the outer outer_constant from the inner STANDARD, but that carries this experiment to its most pathological extreme. (It it legal to compile a library package named STANDARD, but not one named CHARACTER or INTEGER. There seemed to be no need to have a special rule to make such masochistic behavior explicitly illegal.) -- Robert I. Eachus with STANDARD_DISCLAIMER; use STANDARD_DISCLAIMER; function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...