rootcint handling of "not declared" classes

Pasha Murat (murat@cdfsga.fnal.gov)
Tue, 28 Oct 1997 17:07:46 GMT


Hello,

there is a certain problem with rootcint handling of classes it considers
"not defined". To see what the problem is lets assume that we deal with a
large software system with source codes residing in many directories
(a/ and b/ in this example). Suppose sources of class A are located in
directory a/ :

-------------------------------- A.h
class A : public TObject {
B b;
ClassDef(A,1)
};
--------------------

with class B being described in directory b/ .

Now, we use the following linkdef.h:
-------------------------------------------------- linkdef.h
#ifdef __CINT__
#pragma link off all globals
#pragma link off all functions
#pragma link off all classes
#pragma link C++ class A;
#pragma link C++ class B;
#endif
--------------------------------------------------
then we `cd' into directory a/ and try to create CINT dictionary:

>cd a
>rootcint -f a_cint.cc -c linkdef.h A.h

This generates diagnostics:

Class B: Streamer() not declared
Class B: ShowMembers() not declared

which is fine, however (and this is not fine at all!) A::Streamer method
generated by rootcint *does not* contain call to B::Streamer:
----------------------------------------------
void A::Streamer(TBuffer &R__b)
{
// Stream an object of class A. ***** call to B::Streamer is missing here

TObject::Streamer(R__b);
}
----------------------------------------------
The example above shows that there is an implicit assumption that there
is *only one* CINT dictionary for the whole system...
If I want (and it seems to be a pretty reasonable solution) to have a CINT
dictionary per subdirectory, then to generate CINT dictionary for the files
in directory a/ it
is necessary for rootcint to read include files from directory b/.
Therefore, the generated for a/ CINT dictionary will include B::Streamer.
However the same function B::Streamer would also be contained in the dictionary
generated for directory b/ and we end up with having multiple definitions of the
same function and a lot of linker warnings...

One of the ways to resolve this problem is to generate Class::Streamer etc
functions assuming that *all* the classes involved if not defined on the input
stream have their dictionaries generated elsewhere.
I remind that in most of the cases (if not in 100%) correct generation
of the A::Streamer method *does not* require the definition of the class B to
be available. To do it it is quite enough to know only the name of the
class (B in this case).

Any comments ? Regards, Pasha