Hi Matthew, I appreciate you returned back to this issue and shed a new light on it. You are right: when A::vg() is defined in your example, GCC does everything correctly. What I call "bug" is that gcc *does not* complain about missing A::vg(). It just says that (in your example) "A virtual table" is missing... You may certainly disagree with calling this a "bug", but in any case we have here an example of the diagnostics which is rather misleading. Let's take an example from "the life of non-advanced ROOTer": if you accidentally missed ClassImp() macro in some place you end up with having linker complaining about that a bunch of functions you've defined as inlines are missing... And *no single word* about that one which actually caused the diagnostics. It is very difficult for me to agree with you in that this is a good thing... Anyway, your explanation is pretty clear and the rest is mostly a matter of terminology. There is another GCC-related problem however, which might be pretty well IRIX6.2 specific. I also can't exclude that it might have even more limited scope (for example, it might be a local problem at Fermilab). I return to it in hope that you could comment on it as well. It seems that on IRIX 6.2 GCC (we have v2.7.2.1 installed on R10000 platform) *doesn't do* inlining at all. If I compile your example with -O3 which supposedly should turn ON all the optimizations including inlining, I still get the following: /cdf/upgrade/tracking/murat/g3/test>gcc -c -O3 $r1/testa.cc ; nm testa.o | grep f U f__1A Presence of undefined reference points out to that compiler didn't inline A::f(). On AIX 4.2 however (where i installed GCC 2.7.2.2 myself) with -O3 turned ON unresolved reference is not generated, so I guess that (at least some kind) of inlining took place. Thanks once again, Pasha. -------------------------------------------------------------------------------- Matthew D. Langston writes: > 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