Tony Simons <ajhs@xxxxxxxxxxxxxx> 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.