TTree::Branch not recognizing actual class in ROOT 6.18/04

Hello everyone,

this is my code:

test.C:

#include "myevent.hh"
#include "TROOT.h"
#include <iostream>
#include "TTree.h"

using namespace std;

void test() {
  gROOT->ProcessLine(".L myevent.hh+");
  
  TTree* tree = new TTree("tree", "tree");
  MyEvent* event = new MyEvent();
  tree->Branch("event", "MyEvent", &event);
  
} 

myevent.hh:

#ifndef MYEVENT
#define MYEVENT

class MyEvent : public TObject {
public:
   Double_t number;
   MyEvent(){};
   MyEvent(const MyEvent&) = delete;
   
};

#endif

If I go

$ source root-6.16.00/bin/thisroot.sh
$ root -l test.C

this works fine with no errors. Now I log out from my computer account, log in again, and execute

$ source root-6.18.04/bin/thisroot.sh
$ root -l test.C

This gives me
Error in <TTree::Branch>: The actual class (TObject) of the object provided for the definition of the branch "event" does not inherit from MyEvent

To add some context (probably that’s relevant), ROOT 6.16/00 is the precompiled binary that I downloaded from the ROOT website; instead, I have compiled ROOT 6.18/04 from source with

$ cmake -DCMAKE_BUILD_TYPE="Debug"   ../root-6.18.04-source/
$ cmake --build .

Can anyone point out what’s wrong here? Thanks in advance!

Bumping this thread to be sure that no one has any idea about this…

Try:

#include "myevent.hh"
#include "TROOT.h"
#include <iostream>
#include "TTree.h"
#ifdef __CLING__
#include "myevent.h++"
#else
#include "myevent.h"
#endif

using namespace std;

void test() {

  TTree* tree = new TTree("tree", "tree");
  MyEvent* event = new MyEvent();
  tree->Branch("event", "MyEvent", &event);
  
} 

My first section of test.C now looks like this (I assume it was a typo, since your code as is says “myevent.h” doesn’t exist)

#include "TROOT.h"
#include <iostream>
#include "TTree.h"
#ifdef __CLING__
#include "myevent.hh++"
#else
#include "myevent.hh"
#endif

It still produces the same error, and now if I try to run it with root test.C+ (which is the way I’ll have to run my actual code), it even produces this fatal error:

Info in <TUnixSystem::ACLiC>: creating shared library test_C.so
Info in <TUnixSystem::ACLiC>: creating shared library myevent_hh.so
Warning in <ACLiC>: Failed to generate the dependency file for myevent_hh.so
<<< cling interactive line includer >>>:1:10: fatal error: '.' file not found
#include "."
         ^~~
Error in <ACLiC>: Dictionary generation failed!
In file included from input_line_12:6:
././test.C:5:10: fatal error: 'myevent.hh++' file not found
#include "myevent.hh++"
         ^~~~~~~~~~~~~~
Error in <ACLiC>: Dictionary generation failed!

Bumping again… can anyone at least confirm it is a local problem and not a ROOT bug?

Yes, this was what I meant.

It still produces the same error,

Strange.

What does:

.L test.C
c = TClass::GetClass("MyEvent");
if (c) cout << "Isloaded: " << c->IsLoaded() << '\n';

prints?

now if I try to run it with root test.C+

Indeed I did not get the #ifdef correct (however the output is still actually odd). For test.C+ to work you would need to use:

#include "TROOT.h"
#include <iostream>
#include "TTree.h"
#include "myevent.hh"

and

root.exe -b -l -e '.L myevent.h+' 

or use

#include "TROOT.h"
#include <iostream>
#include "TTree.h"
#include "myevent.hh"
#ifdef __ROOTCLING__
#pragma C++ class MyEvent+;
#endif

and use .L test.C+

Cheers,
Philippe.

Thank you! Now this is what my test.C looks like:

#include "TROOT.h"
#include <iostream>
#include "TTree.h"
#include "myevent.hh"
#ifdef __ROOTCLING__
#pragma C++ class MyEvent+;
#endif

using namespace std;

void test() {
  gROOT->ProcessLine(".L myevent.hh++");
  
  TTree* tree = new TTree("tree", "tree");
  MyEvent* event = new MyEvent();
  tree->Branch("event", "MyEvent", &event);
  
  auto c = TClass::GetClass("MyEvent");
  if (c)
    cout << "IsLoaded: " << c->IsLoaded() << endl;
} 

and here’s the output:

$ root -l test.C+
root [0] 
Processing test.C+...
Info in <TUnixSystem::ACLiC>: creating shared library test_C.so
Info in <ACLiC>: script has already been loaded in interpreted mode
Info in <ACLiC>: unloading myevent.hh and compiling it
Info in <TUnixSystem::ACLiC>: creating shared library myevent_hh.so
Error in <TTree::Branch>: The actual class (TObject) of the object provided for the definition of the branch "event" does not inherit from MyEvent
IsLoaded: 1

Again, running this with ROOT 6.16/00 prints no error.

Hi,

You no longer need the line:

  gROOT->ProcessLine(".L myevent.hh++");

In,

#pragma C++ class MyEvent+;

I made a fatal typo. I meant:

#pragma link C++ class MyEvent+;

Cheers,

Philippe.

Thank you for your fast reply. Unfortunately, even aftere these corrections the error doesn’t go away; the class is still loaded.

$ root -l test.C+
root [0] 
Processing test.C+...
Info in <TUnixSystem::ACLiC>: creating shared library test_C.so
Error in <TTree::Branch>: The actual class (TObject) of the object provided for the definition of the branch "event" does not inherit from MyEvent
IsLoaded: 1
//test.C
#include "TROOT.h"
#include <iostream>
#include "TTree.h"
#include "myevent.hh"
#ifdef __ROOTCLING__
#pragma link C++ class MyEvent+;
#endif

using namespace std;

void test() {
  
  TTree* tree = new TTree("tree", "tree");
  MyEvent* event = new MyEvent();
  tree->Branch("event", "MyEvent", &event);
  
  auto c = TClass::GetClass("MyEvent");
  if (c)
    cout << "IsLoaded: " << c->IsLoaded() << endl;
    
} 

Well at this point I’ll just try recompiling ROOT and hope that somehow the error goes away… The only thing I’m very curious about is if anyone can reproduce this, or I have to dig into some research for an installation problem or whatever.

I do this like att
myevent.C (567 Bytes)
Note the ClassDef, ClassImp
and run it in a session

.L myevent.C++
test()

works with 6.16.00 6.18.04, 6.19.01
Otto

I added the ClassDef macro in my code and it worked like a charm, thank you so much!!

My bad for not noticing … Indeed when a class inherits from TObject the ClassDef is compulsory.

My bad for not noticing …

No problem, thank you for helping anyway!

ClassDef is compulsory

Yeah, I only learned about it now, strange that I hadn’t seen anything about it in the documentation. Also it is strange, at this point, that the same code worked fine without ClassDef in the older version…

Hi,
with r6.16.00 it was worse:
root/ACliC did not show an error message but MyEvent had
only the TObject part.
You may try my example which has the

event->Dump();
...
You will not see "number"

Cheers
Otto

PS: What I learned  meanwhile: 
If the compiler doesnt show any more errors
the real (debugging) work begins

Well, that is strange. With ROOT 6.16/00 I was able to successfully fill and read a TTree multiple times with my Event class which didn’t have ClassDef in it… But if it did better work than expected, it’s nothing I’d complain about, I guess :slight_smile: