user541686
user541686

Reputation: 210755

Why doesn't C++ need forward declarations for class members?

I was under the impression that everything in C++ must be declared before being used.

In fact, I remember reading that this is the reason why the use of auto in return types is not valid C++0x without something like decltype: the compiler must know the declared type before evaluating the function body.

Imagine my surprise when I noticed (after a long time) that the following code is in fact perfectly legal:

[Edit: Changed example.]

class Foo
{
    Foo(int x = y);
    static const int y = 5;
};

So now I don't understand:

Why doesn't the compiler require a forward declaration inside classes, when it requires them in other places?

Upvotes: 12

Views: 758

Answers (5)

justin
justin

Reputation: 104708

unlike a namespace, a class' scope cannot be reopened. it is bound.

imagine implementing a class in a header if everything needed to be declared in advance. i presume that since it is bound, it was more logical to write the language as it is, rather than requiring the user to write forwards in the class (or requiring definitions separate from declarations).

Upvotes: 0

Matthieu M.
Matthieu M.

Reputation: 300389

Actually, I think you need to reverse the question to understand it.

Why does C++ require forward declaration ?

Because of the way C++ works (include files, not modules), it would otherwise need to wait for the whole Translation Unit before being able to assess, for sure, what the functions are. There are several downsides here:

  • compilation time would take yet another hit
  • it would be nigh impossible to provide any guarantee for code in headers, since any introduction of a later function could invalidate it all

Why is a class different ?

A class is by definition contained. It's a small unit (or should be...). Therefore:

  • there is little compilation time issue, you can wait until the class end to start analyzing
  • there is no risk of dependency hell, since all dependencies are clearly identified and isolated

Therefore we can eschew this annoying forward-declaration rule for classes.

Upvotes: 3

K-ballo
K-ballo

Reputation: 81409

Function definitions within the class body are treated as if they were actually defined after the class has been defined. So your code is equivalent to:

class Foo
{
    Foo();
    int x, *p;
};
inline Foo::Foo() { p = &x; }

Upvotes: 6

Ben Voigt
Ben Voigt

Reputation: 283901

The standard says (section 3.3.7):

The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, but also of all function bodies, brace-or-equal-initializers of non-static data members, and default arguments in that class (including such things in nested classes).

This is probably accomplished by delaying processing bodies of inline member functions until after parsing the entire class definition.

Upvotes: 10

Mark Ransom
Mark Ransom

Reputation: 308530

Just guessing: the compiler saves the body of the function and doesn't actually process it until the class declaration is complete.

Upvotes: 2

Related Questions