Hello Pasha and Fons, I'd like to reiterate that this is not a bug in gcc/g++. Please see the original thread discussing this problem in the RootTalk Digest at http://root.cern.ch/root/roottalk/0991.html. Pasha originally reported that declaring a function as virtual in a class definition resulted in the gcc/g++ compiler discarding the definitions of methods defined inline within the class definition. Below I have included a slightly simplified example that demonstrates Pasha's original problem. ** begin test.cc example ** class A { public: int f() { return 1; } virtual int vg(); }; int main() { A a; int b = a.f(); } ** end test.cc example ** Pasha was concerned that he didn't see the definition of `A::f()' in test.o when he compiled test.cc using the command `g++ -c test.cc': langston@seto$ g++ -c test.cc langston@seto$ nm -C test.o 0000002c W A::A(void) U A virtual table U A::f(void) 00000000 t gcc2_compiled. 00000000 T main Pasha is certainly correct that `test.o' does not contain the assembly code for `A::f()' (as evidenced in the output of `nm -C test.o' above by the `U' to the left of the symbol `A::f(void)'). However, this is because `test.o' *should not* contain the definition of *any* member functions of `class A' (unless optimization is turned on - see http://root.cern.ch/root/roottalk/0995.html for why this is so). The reason that `test.o' does not contain the definition for `A::f()' is because `class A' is an incomplete type since `A::vg()' is undefined. Had `A::vg()' been defined in `test.cc' (go ahead and try this yourself) then `class A' would have been completely defined and the compiler would have emitted all of the assembly code concerning `class A' into `test.o'. This reason that g++ behaves in this way is a good thing, otherwise some information will be duplicated in each object file that includes the class definition of `class A' (backup copies of inline member functions, compiler generated constructors, debugging information, the internal tables that implement virtual functions, etc.). This is a common problem for C++ compilers (not just g++). The method that the GNU C developers chose to solve this problem was to emit the definitions of inline member function in the same translation unit where the classes vtable is emitted. According to the GNU C manual: "...if a class has any non-inline virtual functions, the vtable will be emitted in the translation unit containing the first one of those.". Therefore, in our `test.cc' example, the definition of `A::f()' will be emitted in the same translation unit where `A::vg()' is defined. Since Pasha never defined the virtual member function is his original example, the definition for `A::f()' was silently discarded. In the "old" days of g++ (specifically the 2.6.x series), the GNU C developers gave us the `interface' and `implementation' pragmas to help us solve the problem of duplicating compiler generated class information in multiple `.o' files (these pragmas are what Pasha referred to in his response below). These pragmas aren't used that much anymore, and certainly not in the common case as exemplified by our `test.cc' example above. Although one *could* use the `#pragma interface/implementation' method to solve this common problem, `pramgas' are generally considered evil and not to be used unless absolutely necessary - at best, pragmas are non-portable. Rather than duplicating that information here, I'll refer the interested reader to the section `C++ Interface' in the GNU C manual. -- Matthew D. Langston Stanford Linear Accelerator Center langston@SLAC.Stanford.EDU (650)926-3279 Pasha Murat wrote: > > Fons Rademakers writes: > > Hi Pasha, > > > > what is the status of this g++ bug? I use g++ all the time in > > -g and -O mode without problems. Does the bug persist when you > > remove the (redundant) inline keyword? I never use "inline" for > > implicit inline functions (maybe thereby avoiding this problem > > which shows only in that case). > > > > Cheers, Fons. > > > -------------------------------------------------------------------------------- > Hi Fons, > > It doesn't matter whether or not word "inline" is present - problem still > persists. Jarek Grebieszkow (a lot of thanks to him!) posted to ROOTTALK a > workaround. I just repeat what he said once again: if each include file > starts from > > #ifdef __GNUG_ > #pragma interface > #endif > > and each source file starts from > > #ifdef __GNUG_ > #pragma implementation > #endif > > GCC does not "forget" about the inlines in the presence of "virtual" declarations. > (ifdef jackets used here not to confuse other compilers, essential is the presence > of pragma's). This solved all my problems. It would also be very interesting to > figure out why this problem doesn't affect ROOT core distribution. > > Regards, Pasha
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:26:21 MET