Container template class compilation problems

Dear Fellows ROOTers,

I’m developing a vector class (TBufferedVector) capable of disk buffered storage through a TSmartTree (TSmartTree = own TTree with sorting, attached).
I want to keep the class as generic as possible to store any kind of object/type inside, hence I am using a template class.
In ROOT 5.34 I am able to compile the class, but after the compilation the dictionary has not been created and I cannot use it because symbols are not defined.

Could you help me to figure out how to make ROOT handle template classes? I have tried to define a LinkDef.h file based on other answers, but it didn’t do the trick.

Many thanks in advance!

TSmartTree.h (1.1 KB)
TBufferedVector.h (1.3 KB)

It would help if you could paste what you called (compiler, linker) and all available error messages :slight_smile:

Dear Axel,

Thanks for replying! Indeed the problem is that I don’t get either any compilation error or runtime error in ROOT 5.34.
After your comment I have tried to do the same with ROOT 6.08 and indeed I got something. I paste what I do respectively in the two versions of ROOT.

ROOT 5.34/30:

ROOT 5.34/30 (heads/v5-34-00-patches@v5-34-28-57-gec27989, Apr 10 2017, 18:18:00 on macosx64)

CINT/ROOT C/C++ Interpreter version 5.18.00, July 2, 2010
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.

WELCOME to ALICE

root [0] .L TSmartTree.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TSmartTree_h.so
root [1] .L TBufferedVector.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TBufferedVector_h.so
root [2] 
root [2] 
root [2] TBufferedVector<TObject*> vect jet
Error: Symbol TBufferedVector is not defined in current scope  (tmpfile):1:
Error: Symbol TObject is not defined in current scope  (tmpfile):1:
Error: G__getvariable: expression  (tmpfile):1:
Error: Symbol vect is not defined in current scope  (tmpfile):1:
(const int)0
*** Interpreter error recovered ***
root [3]

ROOT 6.08/02:

   ------------------------------------------------------------
  | Welcome to ROOT 6.08/02                http://root.cern.ch |
  |                               (c) 1995-2016, The ROOT Team |
  | Built for macosx64                                         |
  | From tag v6-08-02, 2 December 2016                         |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
   ------------------------------------------------------------


WELCOME to ALICE

root [0] .L TSmartTree.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TSmartTree_h.so
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree_linkdef.h, output: ${ALICE_ROOT}/include/TSmartTree_linkdef.h
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.h, output: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.h
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree_linkdef.hh, output: ${ALICE_ROOT}/include/TSmartTree_linkdef.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hh, output: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree_linkdef.hpp, output: ${ALICE_ROOT}/include/TSmartTree_linkdef.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hpp, output: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree_linkdef.hxx, output: ${ALICE_ROOT}/include/TSmartTree_linkdef.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hxx, output: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree_linkdef.hPP, output: ${ALICE_ROOT}/include/TSmartTree_linkdef.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hPP, output: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree_linkdef.hXX, output: ${ALICE_ROOT}/include/TSmartTree_linkdef.hXX
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hXX, output: ${ALICE_PHYSICS}/include/TSmartTree_linkdef.hXX
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree.hh, output: ${ALICE_ROOT}/include/TSmartTree.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree.hh, output: ${ALICE_PHYSICS}/include/TSmartTree.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree.hpp, output: ${ALICE_ROOT}/include/TSmartTree.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree.hpp, output: ${ALICE_PHYSICS}/include/TSmartTree.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree.hxx, output: ${ALICE_ROOT}/include/TSmartTree.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree.hxx, output: ${ALICE_PHYSICS}/include/TSmartTree.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree.hPP, output: ${ALICE_ROOT}/include/TSmartTree.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree.hPP, output: ${ALICE_PHYSICS}/include/TSmartTree.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TSmartTree.hXX, output: ${ALICE_ROOT}/include/TSmartTree.hXX
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TSmartTree.hXX, output: ${ALICE_PHYSICS}/include/TSmartTree.hXX

root [1] 
root [1] .L TBufferedVector.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TBufferedVector_h.so
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector_linkdef.h, output: ${ALICE_ROOT}/include/TBufferedVector_linkdef.h
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.h, output: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.h
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hh, output: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hh, output: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hpp, output: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hpp, output: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hxx, output: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hxx, output: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hPP, output: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hPP, output: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hXX, output: ${ALICE_ROOT}/include/TBufferedVector_linkdef.hXX
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hXX, output: ${ALICE_PHYSICS}/include/TBufferedVector_linkdef.hXX
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector.hh, output: ${ALICE_ROOT}/include/TBufferedVector.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector.hh, output: ${ALICE_PHYSICS}/include/TBufferedVector.hh
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector.hpp, output: ${ALICE_ROOT}/include/TBufferedVector.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector.hpp, output: ${ALICE_PHYSICS}/include/TBufferedVector.hpp
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector.hxx, output: ${ALICE_ROOT}/include/TBufferedVector.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector.hxx, output: ${ALICE_PHYSICS}/include/TBufferedVector.hxx
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector.hPP, output: ${ALICE_ROOT}/include/TBufferedVector.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector.hPP, output: ${ALICE_PHYSICS}/include/TBufferedVector.hPP
Error in <TSystem::ExpandFileName>: input: ${ALICE_ROOT}/include/TBufferedVector.hXX, output: ${ALICE_ROOT}/include/TBufferedVector.hXX
Error in <TSystem::ExpandFileName>: input: ${ALICE_PHYSICS}/include/TBufferedVector.hXX, output: ${ALICE_PHYSICS}/include/TBufferedVector.hXX
root [2] TBuffer
TBuffer
TBuffer3D
TBuffer3DCutTube
TBuffer3DSphere
TBuffer3DTube
TBuffer3DTubeSeg
TBuffer3DTypes
TBufferFile
TBufferJSON
TBufferSQL
TBufferSQL2
TBufferXML
root [2] TBufferedVector<TObject> vect
IncrementalExecutor::executeFunction: symbol '_ZN15TBufferedVectorI7TObjectE5ClassEv' unresolved while linking function '_GLOBAL__sub_I_cling_module_68'!
You are probably missing the definition of TBufferedVector<TObject>::Class()
Maybe you need to load the corresponding shared library?
IncrementalExecutor::executeFunction: symbol '_ZN15TBufferedVectorI7TObjectE8StreamerER7TBuffer' unresolved while linking function '_GLOBAL__sub_I_cling_module_68'!
You are probably missing the definition of TBufferedVector<TObject>::Streamer(TBuffer&)
Maybe you need to load the corresponding shared library?

 *** Break *** segmentation violation
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
[<unknown binary>]
Root >

Thank you for your help! :slight_smile:

Good!

Let’s look into the v6 issue. You’re missing a dictionary for TBufferedVector<TObject>. .L TBufferedVector.h++ doesn’t produce that for you. Adding

#ifdef ROOTCLING
#pragma link C++ class TBufferedVector<TObject>+;
#endif

should fix that: now, .L TBufferedVector.h++ will generate a dictionary for that template instance.

Or you don’t inherit from TObject and you remove the ClassDef part - ROOT doesn’t need those; they are “just” a performance improvement.

The issues regarding ${ALICE_ROOT} and ${ALICE_PHYSICS} are likely caused by a missing definition of these environment variables.

Cheers, Axel.

Dear Axel,

Thanks a lot for your answer!
Unfortunately the compiler directive you suggested does not fix the issue on my side.
With the attached .h I get the following in ROOT:

ROOT 5.34/30:

root [0] .L TSmartTree.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TSmartTree_h.so
root [1] .L TBufferedVector.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TBufferedVector_h.so
root [2] TBufferedVector<TObject> vect
Error: Symbol TBufferedVector is not defined in current scope  (tmpfile):1:
Error: Symbol TObject is not defined in current scope  (tmpfile):1:
Error: Symbol vect is not defined in current scope  (tmpfile):1:
(const int)0
*** Interpreter error recovered ***
root [3] 

ROOT 6.08/02:

root [0] .L TSmartTree.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TSmartTree_h.so
root [1] .L TBufferedVector.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/alice_sw/alice-MTR-utils/./TBufferedVector_h.so
root [2] TBufferedVector<TObject> vect
(TBufferedVector<TObject> &) Name: TObject Title: Basic ROOT object
root [3] 

As you can notice the line you suggested is working in ROOT 6 but not in ROOT 5.
At the moment I have some other problems. While on one hand the TSmartTree is perfectly working (tested in other macros, working as expected) the TBufferedVector interface isn’t.
The Idea was to make TBufferedVector an interface to access the TSmartTree as a vector, but even if I managed to fill the inner fSmartTree with some objects, the TBufferedVector::At method doesn’t returns correctly the object linked to the fContentPointer.
Setting fSmartTree to public allowed me to check if the TSmartTree::GetSortedEntry method was working as intended and it was, but at the same time the TBufferedVector::At method wasn’t and I can’t figure out what is going on there!

Do you have any clue on what’s wrong with my code?

Thank you in advance!


TSmartTree.h (1.4 KB)
TBufferedVector.h (1.4 KB)

root [2] TBufferedVector<TObject> vect
Error: Symbol TBufferedVector is not defined in current scope  (tmpfile):1:
Error: Symbol TObject is not defined in current scope  (tmpfile):1:
Error: Symbol vect is not defined in current scope  (tmpfile):1:
(const int)0

This indicates that the #prama link class was not seen (or not properly interpreted) by ACLiC (more exactly by rootcint called by ACLiC). Likely in part because the line give by Axel has a fatal type and in not appropriate for v5.

#ifdef __ROOTCINT__
// use #ifdef __ROOTCLING__
// if you need to support only v6.
#pragma link C++ class TBufferedVector<TObject>+;
#endif

will work in both v5 and v6

Dear Philippe, Axel, All,

Thanks a lot for your answer. Unfortunately that did not do the trick.
I have managed to fix my class, and in ROOT 6 everything is working (objects are correctly retrieved from the TSmartTree and returned by TBufferedVector::At() and operator [].
Unfortunately neither __ROOTCINT__ nor __ROOTCLING__ make the class correctly recognised by ROOT 5: now I have just left the #pragma link C++ class TBufferedVector<TObject>+; without surrounding #ifdef and #endif and added ClassDefT(TBufferedVector<T>,1) that makes the autocompletion available.

I think I am getting one step closer to the solution. I have managed to make my vector correctly in ROOT 6, while in ROOT 5 I still have something to think about:

ROOT 5.34/30:

root [0] .L TSmartTree.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/cernbox/Dottorato/Alirootproject/Dottorato/OCDB_AMANDA_filippo/./TSmartTree_h.so
root [1] .L TBufferedVector.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/cernbox/Dottorato/Alirootproject/Dottorato/OCDB_AMANDA_filippo/./TBufferedVector_h.so
root [2] TBufferedVector<TObject> vect
root [3] vect.Add(gRandom)
root [4] static_cast<TRandom*>(vect[0])->TRandom::Rndm()

 *** Break *** segmentation violation
 Generating stack trace...
 0x000000010c535e9f in Cint::G__ExceptionWrapper(int (*)(G__value*, char const*, G__param*, int), G__value*, char*, G__param*, int) (in libCint.5.so) + 63
 0x000000010c5d960b in G__execute_call (in libCint.5.so) + 75
 0x000000010c5d9a52 in G__call_cppfunc (in libCint.5.so) + 818
 0x000000010c5b0d9c in G__interpret_func (in libCint.5.so) + 5164
 0x000000010c59ee0f in G__getfunction (in libCint.5.so) + 5839
 0x000000010c6a04db in G__getstructmem(int, G__FastAllocString&, char*, int, char*, int*, G__var_array*, int) (in libCint.5.so) + 4139
 0x000000010c59e407 in G__getfunction (in libCint.5.so) + 3271
 0x000000010c593055 in G__getitem (in libCint.5.so) + 1445
 0x000000010c58e5e3 in G__getexpr (in libCint.5.so) + 30547
 0x000000010c59f09e in G__getfunction (in libCint.5.so) + 6494
 0x000000010c593055 in G__getitem (in libCint.5.so) + 1445
 0x000000010c58e5e3 in G__getexpr (in libCint.5.so) + 30547
 0x000000010c60c317 in G__exec_statement (in libCint.5.so) + 27815
 0x000000010c574ca4 in G__exec_tempfile_core(char const*, __sFILE*) (in libCint.5.so) + 1124
 0x000000010c574836 in G__exec_tempfile_fp (in libCint.5.so) + 22
 0x000000010c616352 in G__process_cmd (in libCint.5.so) + 7266
 0x000000010bf2bc7f in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) (in libCore.5.so) + 831
 0x000000010bbd6663 in TRint::HandleTermInput() (in libRint.5.so) + 659
 0x000000010bf6361a in TUnixSystem::CheckDescriptors() (in libCore.5.so) + 330
 0x000000010bf6bf5b in TMacOSXSystem::DispatchOneEvent(bool) (in libCore.5.so) + 427
 0x000000010bfd408a in TSystem::InnerLoop() (in libCore.5.so) + 26
 0x000000010bfd3ede in TSystem::Run() (in libCore.5.so) + 206
 0x000000010bf77d34 in TApplication::Run(bool) (in libCore.5.so) + 36
 0x000000010bbd5fb4 in TRint::Run(bool) (in libRint.5.so) + 1428
 0x000000010b8abebf in main (in root.exe) + 79
 0x00007fffe7112235 in start (in libdyld.dylib) + 1

ROOT 6.08/02:

root [0] .L TSmartTree.h++
root [1] .L TBufferedVector.h++
root [1]
root [1]
root [2] TBufferedVector<TObject> vect
(TBufferedVector<TObject> &) Name: TBufferedVector<TObject> Title: 
root [3] vect.Add(gRandom)
root [4] static_cast<TRandom*>(vect[0])->TRandom::Rndm()
(Double_t) 0.807771

If you have any clue on the reason why I am experiencing such different behaviours in the two version of ROOT don’t hesitate to write it down!
Cheers!

Gabriele

Hi Gabriele,

You must have encountered one of the many quirk of CINT that made us to decide to develop Cling as a replacement. The best might to move completely to ROOT v6 and forget about v5.

Cheers,
Philippe

Dear Philippe,

Unfortunately this piece of code has to be used along with ALICE libraries which are not intended to be compiled in ROOT 6.
I will keep the code for the next updates of our code! :slight_smile:
Thanks again for your help!

Gabriele

In v5, after executing:

root [0] .L TSmartTree.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/cernbox/Dottorato/Alirootproject/Dottorato/OCDB_AMANDA_filippo/./TSmartTree_h.so
root [1] .L TBufferedVector.h++
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/Gabriele/cernbox/Dottorato/Alirootproject/Dottorato/OCDB_AMANDA_filippo/./TBufferedVector_h.so

what does

.class TBufferedVector<TObject>

(note the periode in front of class) prints?

Cheers,
Philippe.

PS. ALICE needs to move to v6 asap :slight_smile: :slight_smile:

Dear Philippe,

Here is what I get:

root [1] .class TBufferedVector<TObject>
Error: no such template TBufferedVector<TObject> :0:
*** Interpreter error recovered ***
root [2] 

Cheers!

Gabriele

OK, so the pragma did not take … What is the exact code you use for that?

I attach right after the two headers I am using.
Cheers!

Gabriele

TBufferedVector.h (1.7 KB)
TSmartTree.h (1.3 KB)

Strange … as is … with v5.34/37, I get:

root [1] .L ~/Downloads/TSmartTree.h+
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/pcanal/Downloads/TSmartTree_h.so
root [2] .L ~/Downloads/TBufferedVector.h+
Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/pcanal/Downloads/TBufferedVector_h.so
root [3] .class TBufferedVector<TObject>
===========================================================================
class TBufferedVector<TObject>
 size=0x2b8 FILE:/Users/pcanal/Downloads/TBufferedVector_h.so LINE:-1
 (tagnum=3634,voffset=-1,isabstract=0,parent=-1,gcomp=0:-1,funcs(dn21=~xcpd)=71)
List of base class--------------------------------------------------------
0x0        public: TObject //Basic ROOT object
List of member variable---------------------------------------------------

I’ve just tried to recompile and it works! I don’t know what happened before!
I still have problems with child classes: I am generating a custom example for my other thread, stay tuned! :grin:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.