TITLE: Danger in using forward declarations for classes. PROBLEM: In some circumstances, the use of forward class declarations can cause the introduction of difficult bugs. RESPONSE: Mark Terribile (mat@mole-end) In article <1991Jul17.015538.17897@cpsc.ucalgary.ca>, chmilar@cpsc.ucalgary.ca (Michael Chmilar) writes: > The following example points out an implementation bug ... Actually, it's a language weakness. It's known, and it bites someone from time to time. I don't believe that the ANSI committee is thinking about it, but I'm not sure. Since it *has* bitten at least one more person, I'm cross-posting it to comp.std.c++ in the hope of stimulating some discussion there. > class Item {}; > class ItemA : public Item {}; > class ItemB : public Item {}; > . . . > class ItemAB; // pre-declaration to allow pointers to be declared > // in the next class. The declaration of ItemAB is now incomplete, and an ItemAB* is a pointer to an incomplete type. As a result, the ambiguity checks and offset adjustments necessary to convert an ItemAB* to an ItemA* or an ItemB* are not available. > class Head > { > public: > Item* first() { return firstItemInList; } > }; > class HeadB : public Head > { > public: > ItemAB* first() { return (ItemAB*)(ItemB*)Head::first(); } > }; At this point, any conversion between ItemAB* and ItemB* is a re-interpretation (C-style cast) of the bit pattern instead of the pointer-adjusting inheritance conversion. > class ItemAB : public ItemA, public ItemB > { > }; Ah, NOW the conversion of ItemB* into ItemAB* is refined from a bit-pattern reinterpretation to an inheritance conversion. > The error may be eliminated by moving the definition of class ItemAB to > the point in the code where it has been predeclared. ... I understand > _how_ the error occurs. ... Then you understand that it is a language weakness, not a compiler error. (Of course, the lack of a warning might be a weakness in the compiler, but it is not, to my knowledge, an error.) > ... What I find disturbing is that the incorrect code compiles, and the > translator does not produce any error or warning messages. ... It *is* a known problem, though. > This is a very dangerous bug, which can lead to programs which do not > work correctly, for no apparent reason. I only traced the problem by looking > at the C code generated from the translator, ... Ouch! I think you deserve the order of the Silver *.* . Seriously, it would be nice if forward class declarations could specify the inheritance. The forward declaration and the real declaration would have to agree, and an absent inheritance specification on a forward declaration that was filled on the real declaration could generate an error or at least a warning.