Forward declaration and usage rules
llewelly@xmission.com
llewelly@xmission.com
Tue Jun 29 13:05:00 GMT 2004
Tony Simons <ajhs@dcs.shef.ac.uk> writes:
> I have compiled C++ code using g++ version 2.95.3 that seems to allow forward
> usage of *value*-types in a class declaration, against my expectations. I only
> expected to be allowed forward usage of pointer-types and reference-types. Note
> that this only applies to forward uses in the *declaration* - I have to include
> full headers before I can compile *definitions" of the member functions.
>
> Does C++ allow arbitrary use of forward-declared types in class declarations?
> If not, does g++ relax these rules on forward declarations? Would my code
> therefore not port to other C++ compilers? Has the C++ standard changed
> recently to allow forward use of value-types inside class declarations? Or is
> this actually a bug in g++?
>
> My actual example is a library of Real, Imaginary and Complex numbers (all
> value-types), for which mutually-recursive definitions would be very useful, if
> this style is eventually kosher and portable. A cut-down model of the
> phenomenon is given below, which I have also tested:
>
> --Tony Simons
>
>
> // in file A.h =========================
>
> class B; // forward declaration
>
> class A {
> public:
The fact that this is inside a class decl is irrelevant.
> A::A(float x);
> B foo(int x) const; // Unexpectedly OK! Returns a B value
> B bar(B b) const; // Unexpectedly OK! Accepts a B value too
The limitation on incomplete types is that one cannot create an object
of that type, or take the size of that type. Here you do niether
of those; you merely use the type in a declaration. This is
well-formed. See 3.9 .
> private:
> float f;
> };
>
> #include "B.h" // the full include is required here...
>
> inline A::A(float x) : f(x) {}
>
> inline B A::foo(int x) const {
> return B(x); // ...for this to compile, and also...
Here you create an object of type B. Therefor B must be complete at
this point.
> }
>
> inline B A::bar(B b) const {
> return B(b); // ...for this to compile, as expected.
> }
gcc 3.4 and comneau both report only one error for your code:
tn.cc:44: error: 'main' must return 'int'
tn.cc:44: error: return type for 'main' changed to 'int'
which has nothing to do with you question and is trivially fixed.
More information about the Gcc-help
mailing list