Topic: Incomplete types and nested classes


Author: dalle@diab.se (Jan-Erik Dahlin)
Date: 7 Sep 92 19:01:32 GMT
Raw View
steve@taumet.com (Steve Clamage) recently wrote about forward declaration
of nested classes:

> You do it the same way you handle any other forward declaration.
> You have to be careful about scopes.
>
>  class A {
>    public:
>      class C; // forward declaration of A::C
>      class B {
>   C *p; // pointer to A::C
>      };
>      class C {
>   B *p; // pointer to A::B
>      };
>  };
>

How about incomplete types and nested classes? What happens if we skip
the first declaration of class C? I ran into the problem when compiling
some old C code.

Section 9.1, paragraph 2 of the draft says: "A class declaration
introduces the class name into the scope where it is declared and hides
any class, object, function or other declaration of that name in an
enclosing scope."

Paragraph 3: "An elaborated-type-specifier can also be used in the
declarations of objects and functions. It differs from a class
declaration in that if a class of the elaborated name is in scope the
elaborated name will refer to it."

What happens if no class with that name is found in scope???

Paragraph 4 has the following example: "A name declaration takes effect
immediately after the identifier is seen. For example,

 class A * A;

first specifies A to be the name of a class and the redefines it as
the name of a pointer to an object of that class."

I guess this means that class A is introduced into the current scope if
not defined earlier.

Example:

  class A {
    public:
      class B *bp; // pointer to A::B or B?
     f(void);
  };

  class B {
   public:
      int memb;
  };

 A::f()
 {
     bp->memb = 4711; // Is this legal?
 }

When the elaborated class specifier for B is seen, should the name be
introduced in the scope of class A (as in a nested class declaration)
or the scope enclosing A?

I think that the declaration 'class B *bp;' should introduce (a nested)
class B in the scope of A. The declaration of class B will introduce a
new type in the file/global scope. When 'bp' is used in A::f() it is a
pointer to the local class B in A's scope, which still is incomplete.
Since both Cfront and gcc accept the above declarations without complaint
I assume I've misinterpreted the standard. Could someone, please,
straighten things out for me?

>
> Steve Clamage, TauMetric Corp, steve@taumet.com
> Vice Chair, ANSI C++ Committee, X3J16

       /Jan-Erik Dahlin
--
"Sometimes the magic works and sometimes it doesn't."
 Chief Dan George of the Sioux Indian tribe, after an unsuccessful rain dance.