Includes for dictionary

I have a class header bar.h which looks as follow:

class foo; class bar: public TObject { ... foo *get_foo (); ClassDef(bar,1) };
I have a problem to compile the dictionary of bar, since the class foo is not defined; I should include foo.h at the top of bar.h, but this creates too many dependency in my code.
As fix I use:

#ifdef G__DICTIONARY #include "foo.h" #else class foo #endif
at the beginning.

Is this the correct way? Putting the include in the linkdef does not helps.

Hi,

What’s the problem with your dictionary and the forward declared class foo (i.e. without your include hacks)? It works for me. Can you post the compiler output, your dictionary, the command line showing how you create it, your root version, and you platform (OS/compiler)?
Axel.

Well maybe with that simple foo-bar example the problem is not there.
In my dictionary file I find a line like the following:

and than the compiler, which has nothing more than the forward declaration, complains as follows:

bar_dict.cc: In member function ‘virtual void bar::Streamer(TBuffer&)’: bar_dict.cc:222: error: invalid use of undefined type ‘struct foo’ bar.hh:22: error: forward declaration of ‘struct db_run’

I use rootcint (from root v5.13.02) as follow:

The compiler is gcc 4.1 from Debian GNU/Linux Sid.

If you really want I cand send the real files but it’s a large project.

Thanks, Eto

Hi,
please attach bar.hh.
Axel.

Hi,
the bar.hh is called bx_barn.hh and is attached as well its linkdef.

(I had to remove a trailing h to header files, since the forum forbid .hh extension)

Alessandro
bx_barnLinkDef.h (830 Bytes)
bx_barn.h (1.89 KB)

Hi,

the problem is slightly different. You’re trying to create the I/O functions to store e.g. a map<int, map_channels*>. For that, ROOT needs to be able to write and read objects of type map_channels - the ones pointed to by the value’s pointers. And for that it needs to be able to access the full class definition of map_channels - not just the forward declaration.

You have thus two options: remove the recursive includes on the other side, i.e. allow bx_barn.hh to include the others, but remove #include bxb_barn.hh statements from them. Or create just one dictionary for all these classes - rootcint can take more than just one header as argument; don’t forget to also put all classes into one Linkdef.h.

Cheers, Axel.

Hi,
I see, maybe my simple foo/bar example where too sinthetic.
In any case, I can’t create just one dictionary object, without modifing the Makefile rules and I prefer to avoid this path.
The dependency problem is not a recursive include, but simply that all the code includes that bx_barn.hh header and it’s a bit annoing to recompile everithing just for modification to a sub include (i.e. db_channel.hh).

Is the macro G__DICTIONARY a stable simble? In that case the first solution I used could be fine. Else I will add a macro myself when compiling dictionary and use it in place of G__DICTIONARY.

Thanks, Alessandro

Hi Alessandro,

[quote=“eto”]maybe my simple foo/bar example where too sinthetic.[/quote]Very much so, yes.

[quote=“eto”]In any case, I can’t create just one dictionary object, without modifing the Makefile rules and I prefer to avoid this path.[/quote] That’s too bad, as this is definitely the way to go. You should think of a dictionary as “one per library”, not “one per header”.

[quote=“eto”]Is the macro G__DICTIONARY a stable simble?[/quote]Yes, it doesn’t change. But I would recommend not to do what you’re trying to do. This will screw up your dependencies (you will need to re-generate the dictionaries if any of the included map classes changes, but make won’t, as it doesn’t see that dependency), and it will make problems a lot harder to track down, because the context is different for the compiler and the dictionary generator. I really recommend to build one dictionary per library.

Cheers, Axel.

Hi,
I checked what happens to have just one large dictionary files, and it is not too reasonable: I have a dictonary files 30000 lines long which takes 1.35 minutes to compile (with 200MB of ram). Doing sublibraries is excluded, since all the parts are extremelly related (and this would create the very same problem I’m trying to solve).

And with this aproach even ccache is useless since for any modification I have almost 2 minuts in compiling the dictionaries.

/alessandro

If this is the original problem, you might also be able to solve the issue by adding a simple#pragma extra_include "map_channels.h"(replacing map_channels.h by the proper include file :slight_smile: ). This will tell rootcint to include that file in addition to the files that were passed to it as argument into the generated dictioanry.

Cheers,
Philippe.