rfg@ICS.UCI.EDU (12/31/89)
In recent versions of g++ (1.36.0, 1.36.1, 1.36.2-) typedefs which are nested within class declarations are given a scope which is local to the class declaration itself. This causes examples like the following to get compile-time errors: --------------------------------------------------------------------------- struct foo { typedef foo* foo_p; void member (foo_p); }; void foo::member (foo_p p) // ERROR: `foo_ptr' undeclared, outside of functions { } --------------------------------------------------------------------------- Such errors illustrate two separate problems with g++. First, it is obvious that g++ does not extend the scope of `member' entities (including, in this case, `member typedefs') to the formal parameter lists of member function definitions which occur outside of the class declaration itself. This is a shame because this fact also makes it illegal to write clever default parameter expressions as illustrated in the following example: --------------------------------------------------------------------------- struct foo { int i; void member (int); }; void foo::member (int arg = i) // ERROR: `i' undeclared, outside of functions { } --------------------------------------------------------------------------- The second (and far more serious) problem is that by treating nested typedefs as local to the classes in which they are nested, g++ is deviating unnecessarily from the behavior of Cfront 2.0 (which gives class-nested typedefs global scope). Thus, the first example above compiles without error using Cfront 2.0, but gets errors using recent editions of g++. The fix is simply to have g++ give class-nested typedefs global scope. The following short patch implements this change. (Your line numbers may vary.) Note that it may *someday* be a good idea to treat class-local typedefs as being local to the classes in which they are nested, but that should not happen yet because (a) the C++ community should first embrace and bless such a change, and (b) if typedefs can be local to a class, then the extension of the scope of class-local entities to the formal parameter lists of class member functions should also be implemented at the same time (in order to prevent bogus errors on examples like the first one shown above). // rfg *** cplus-decl2.c- Thu Dec 7 12:54:18 1989 --- cplus-decl2.c Sat Dec 30 11:41:33 1989 *************** *** 372,378 **** { TREE_NONLOCAL (value) = 1; ! CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; ! pushdecl_class_level (value); ! return value; } --- 372,377 ---- { TREE_NONLOCAL (value) = 1; ! pushdecl_top_level (value); ! return void_type_node; }