Class dictionary file errors with gcc

Dear you,

My ROOT:ROOT 5.34/00 (branches/v5-34-00-patches@44569, Jun 05 2012, 15:31:56 on linux)
GCC: gcc version 4.4.5 20101112 (Red Hat 4.4.5-2) (GCC)

When I compile the class dictionary .cpp file with gcc, it shows the following errors. It seems that if I add these ROOT header files (TGNumberEntry.h … which appears in the error messages) into the ‘rootcint’ commands, the errors will disappear.

However I think it should not necessary to add the ROOT header files in the rootcint command line. Maybe there are some stupid errors in my program.

Any help or advice is appreciated.
Han

rootcint -f classDict.cpp -c -DLINUX TBoard.h TControl.h TModV785.h TModV785N.h TModV775.h TModV775N.h TModV830.h TEvtBuilder.h TClientEvtBuilder.h TControlFrame.h TDataFileBuilder.h TMasterTask.h TGTextEntry.h classLinkDef.h

g++ -c -O2 -D LINUX -pthread -m32 -I/opt/root/include -o classDict.o classDict.cpp

In file included from /opt/root/include/TObject.h:230,
from classDict.h:32,
from classDict.cpp:17:
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator>>(TBuffer&, Tmpl*&) [with Tmpl = TGNumberEntry]’:
classDict.cpp:1084: instantiated from here
/opt/root/include/TBuffer.h:373: error: invalid use of incomplete type 'struct TGNumberEntry’
TControlFrame.h:28: error: forward declaration of ‘struct TGNumberEntry’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator>>(TBuffer&, Tmpl*&) [with Tmpl = TGLabel]’:
classDict.cpp:1085: instantiated from here
/opt/root/include/TBuffer.h:373: error: invalid use of incomplete type 'struct TGLabel’
TControlFrame.h:23: error: forward declaration of ‘struct TGLabel’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator>>(TBuffer&, Tmpl*&) [with Tmpl = TGTextButton]’:
classDict.cpp:1086: instantiated from here
/opt/root/include/TBuffer.h:373: error: invalid use of incomplete type ‘struct TGTextButton’
/opt/root/include/TGFrame.h:51: error: forward declaration of ‘struct TGTextButton’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator>>(TBuffer&, Tmpl*&) [with Tmpl = TGTextView]’:
classDict.cpp:1098: instantiated from here
/opt/root/include/TBuffer.h:373: error: invalid use of incomplete type 'struct TGTextView’
TControlFrame.h:24: error: forward declaration of ‘struct TGTextView’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator<<(TBuffer&, const Tmpl*) [with Tmpl = TGNumberEntry]’:
classDict.cpp:1110: instantiated from here
/opt/root/include/TBuffer.h:380: error: invalid use of incomplete type 'struct TGNumberEntry’
TControlFrame.h:28: error: forward declaration of ‘struct TGNumberEntry’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator<<(TBuffer&, const Tmpl*) [with Tmpl = TGLabel]’:
classDict.cpp:1111: instantiated from here
/opt/root/include/TBuffer.h:380: error: invalid use of incomplete type 'struct TGLabel’
TControlFrame.h:23: error: forward declaration of ‘struct TGLabel’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator<<(TBuffer&, const Tmpl*) [with Tmpl = TGTextButton]’:
classDict.cpp:1112: instantiated from here
/opt/root/include/TBuffer.h:380: error: invalid use of incomplete type ‘struct TGTextButton’
/opt/root/include/TGFrame.h:51: error: forward declaration of ‘struct TGTextButton’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator<<(TBuffer&, const Tmpl*) [with Tmpl = TGTextView]’:
classDict.cpp:1124: instantiated from here
/opt/root/include/TBuffer.h:380: error: invalid use of incomplete type 'struct TGTextView’
TControlFrame.h:24: error: forward declaration of ‘struct TGTextView’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator>>(TBuffer&, Tmpl*&) [with Tmpl = TThread]’:
classDict.cpp:1190: instantiated from here
/opt/root/include/TBuffer.h:373: error: invalid use of incomplete type 'struct TThread’
TControl.h:21: error: forward declaration of ‘struct TThread’
/opt/root/include/TBuffer.h: In function ‘TBuffer& operator<<(TBuffer&, const Tmpl*) [with Tmpl = TThread]’:
classDict.cpp:1197: instantiated from here
/opt/root/include/TBuffer.h:380: error: invalid use of incomplete type 'struct TThread’
TControl.h:21: error: forward declaration of 'struct TThread’
make: *** [classDict.o] Error 1

Hi,

Could you provide a minimal example reproducing the problem?

Philippe.

Dear Philippe,

After I add all the ‘headerfile’ into the rootcint command line, these is no error anymore.
I change:
rootcint -f classDict.cpp -c -DLINUX TBoard.h TControl.h TModV785.h TModV785N.h TModV775.h TModV775N.h TModV830.h TEvtBuilder.h TClientEvtBuilder.h TControlFrame.h TDataFileBuilder.h TMasterTask.h TGTextEntry.h classLinkDef.h [color=#FF0000](This classDict.cpp do not cause these errors under Windows 7 with VC9.0, but under Linux with gcc these error appear)[/color]
to:
rootcint -f classDict.cpp -c -DLINUX TBoard.h TControl.h TModV785.h TModV785N.h TModV775.h TModV775N.h TModV830.h TEvtBuilder.h TClientEvtBuilder.h TControlFrame.h TDataFileBuilder.h TMasterTask.h [color=#FF0000]TQObject.h TGTextEntry.h TGNumberEntry.h TGLabel.h TGButton.h TGTextView.h TThread.h [/color]classLinkDef.h[color=#FF0000](This works ok, on both Windows and Linux)[/color]

In one of my own class (inherit form TGMainFrame) definition , I use class declarations such as:

class TGMainFrame;
class TGVerticalFrame;
class TGHorizontalFrame;
class TGWindow;
class TGLabel;
class TGTextView;
class TGTextEntry;
class TGTextButton;
class TGText;
class TGNumberEntry;

and then “#include” the corresponding ‘.h’ file in the ‘.cpp’ file. I think the rootcint can not find and include these header files. And I used the ‘ClassDef()’ and ‘ClassImp()’ macro in this classes.

However, a very strange thing is, I have another [color=#FF0000]very similar [/color]GUI class(inherit form TGMainFrame), [color=#FF0000]without[/color] the ‘ClassDef()’ and ‘ClassImp()’ macro, it works ok [color=#FF0000]even without [/color]the ‘dictionary’ file.
So I think maybe I have mistakes in my new program.

I am sorry that I can not prepare a minimal example reproducing the problem.

Best wishes,
Han

[quote]In one of my own class (inherit form TGMainFrame) definition , I use class declarations such as:[/quote]If your class inherits from TGMainFrame, I don’t think it is legal C++ to only ‘forward’ declare it, instead the header file should #include the TGMainFrame header file.

Another thing that come to mind is that you might have requested the old I/O for you class in the Linkdef file. When using the old I/O you must pass directly or indirectly the header file to rootcint that defines all the data members types. To request the new I/O use:#pragma link C++ class ABC+; // the + request the new I/Oor you can also disable the I/O by setting the class version to zeroclass ABC { .... ClassDef(ABC,0);.

[quote]/opt/root/include/TBuffer.h: In function ‘TBuffer& operator<<(TBuffer&, const Tmpl*) [with Tmpl = TThread]’:
classDict.cpp:1197: instantiated from here[/quote]The TThread data member should probably be marked transient and/or disable the I/O for the class containing it. (TThread object can not be saved).

Cheers,
Philippe.

Dear Philippe,
I prepared a minimal example reproducing the problem. This example is prepared for another question(TQObject 'signal' from TThread cause GUI carsh), however I find that it can reproduce this problem too.

If you have time please pay some attention to this question.

Thank you,
Han
guicrash.rar (17.5 KB)

Try with:

#ifdef __CINT__ #pragma link C++ class TTestFrame+; #pragma link C++ class TTestTask+; #pragma link C++ class TTestThread+; #endif

Cheers,
Philippe.

Dear Philippe,

This method do not work. It shows the following messages:
rootcint -f classDict.cpp -c -DLINUX TTestThread.h TTestFrame.h TTestTask.h classLinkDef.h
g++ -c -O2 -D LINUX -pthread -m32 -I/usr/local/root/include -o TTestThread.o TTestThread.cpp
g++ -c -O2 -D LINUX -pthread -m32 -I/usr/local/root/include -o TTestFrame.o TTestFrame.cpp
g++ -c -O2 -D LINUX -pthread -m32 -I/usr/local/root/include -o TTestTask.o TTestTask.cpp
g++ -c -O2 -D LINUX -pthread -m32 -I/usr/local/root/include -o classDict.o classDict.cpp
In file included from /usr/local/root/include/TObject.h:230,
from classDict.h:32,
from classDict.cpp:17:
/usr/local/root/include/TBuffer.h: In function ‘TBuffer& operator>>(TBuffer&, Tmpl*&) [with Tmpl = TGTextButton]’:
classDict.cpp:248: instantiated from here
/usr/local/root/include/TBuffer.h:373: error: invalid use of incomplete type ‘struct TGTextButton’
/usr/local/root/include/TGFrame.h:51: error: forward declaration of ‘struct TGTextButton’
/usr/local/root/include/TBuffer.h: In function ‘TBuffer& operator<<(TBuffer&, const Tmpl*) [with Tmpl = TGTextButton]’:
classDict.cpp:254: instantiated from here
/usr/local/root/include/TBuffer.h:380: error: invalid use of incomplete type ‘struct TGTextButton’
/usr/local/root/include/TGFrame.h:51: error: forward declaration of ‘struct TGTextButton’
make: *** [classDict.o] Error 1

Best wishes,
Han

You need to add:
#include "TGButton.h"
As Philippe already mentioned … a forward declaration “class SomeClass;” is NOT sufficient. You really need to #include “SomeClass.h”

[quote]This method do not work. It shows the following messages:[/quote]It does for me (or it must if things are going right!). Did the classDict.cpp get regenerate (i.e. rootcint called) after your change the LinkDef file? Which version of ROOT are you using?

Philippe.

Dear Philippe,

Thank you very much.
You are right, I delete the ‘class dictionary’ file ‘classDict.cpp’ and rebuild it again with rootcint, then it works.

Best wishes,
Han