The problem is more complex than I thought.
While preparing a “trial” I noticed that TTree::SetBranchAddress" misbehaves, too.
The “trial.cxx” (requires “hsimple.root” from the “tutorials”): [code]#include “TFile.h”
#include “TChain.h”
#include “TBranch.h”
#include “TString.h”
#include “TObjString.h”
#include
void trial(void)
{
#if 1 /* 0 or 1 */
TFile file = new TFile(“hsimple.root”);
TTree tree = (TTree)file->Get(“ntuple”);
#else / 0 or 1 /
TChain tree = new TChain(“ntuple”, “ntuple”);
tree->Add(“hsimple.root”);
// tree->SetBranchStatus("", 1);
// tree->SetBranchStatus(“px”, 1);
// std::cout << "fTreeNumber = " << tree->GetTreeNumber() << std::endl;
tree->LoadTree(0); // REQUIRED
// std::cout << "fTreeNumber = " << tree->GetTreeNumber() << std::endl;
#endif / 0 or 1 */
TBranch *p = ((TBranch *)-1);
Int_t r;
Float_t px, fake_px;
Float_t *pxp = new Float_t();
Float_t *fake_pxp = new Float_t();
Int_t ix;
Int_t *ixp = new Int_t();
TString s;
TString *sp = new TString();
TObjString os;
TObjString *osp = new TObjString();
// Float_t … (should be fine)
std::cout << std::endl << "ALL should be FINE … " << std::endl;
p = ((TBranch *)-1);
r = tree->SetBranchAddress(“px”, &px, &p);
std::cout << "Float_t … " << r << std::endl;
std::cout << "p = " << p << std::endl;
r = tree->SetBranchAddress(“px”, &px);
std::cout << "Float_t … " << r << std::endl;
r = tree->SetBranchAddress(“px”, pxp);
std::cout << "Float_t … " << r << std::endl;
r = tree->SetBranchAddress(“px”, &pxp);
std::cout << "Float_t … " << r << std::endl;
// Int_t … (should fail)
std::cout << std::endl << "ALL should FAIL … " << std::endl;
p = ((TBranch *)-1);
r = tree->SetBranchAddress(“px”, &ix, &p);
std::cout << "Int_t … " << r << std::endl;
std::cout << "p = " << p << std::endl;
r = tree->SetBranchAddress(“px”, &ix);
std::cout << "Int_t … " << r << std::endl;
r = tree->SetBranchAddress(“px”, ixp);
std::cout << "Int_t … " << r << std::endl;
r = tree->SetBranchAddress(“px”, &ixp);
std::cout << "Int_t … " << r << std::endl;
// TString … (should fail)
std::cout << std::endl << "ALL should FAIL … " << std::endl;
p = ((TBranch *)-1);
r = tree->SetBranchAddress(“px”, &s, &p);
std::cout << "TString … " << r << std::endl;
std::cout << "p = " << p << std::endl;
r = tree->SetBranchAddress(“px”, sp);
std::cout << "TString … " << r << std::endl;
r = tree->SetBranchAddress(“px”, &sp);
std::cout << "TString … " << r << std::endl;
// TObjString … (should fail)
std::cout << std::endl << "ALL should FAIL … " << std::endl;
p = ((TBranch *)-1);
r = tree->SetBranchAddress(“px”, &os, &p);
std::cout << "TObjString … " << r << std::endl;
std::cout << "p = " << p << std::endl;
r = tree->SetBranchAddress(“px”, osp);
std::cout << "TObjString … " << r << std::endl;
r = tree->SetBranchAddress(“px”, &osp);
std::cout << "TObjString … " << r << std::endl;
// nonexistent branch … (should fail)
std::cout << std::endl << "ALL should FAIL … " << std::endl;
p = ((TBranch *)-1);
r = tree->SetBranchAddress(“fake_px”, &fake_px, &p);
std::cout << "nonexistent branch … " << r << std::endl;
std::cout << "p = " << p << std::endl;
r = tree->SetBranchAddress(“fake_px”, &fake_px);
std::cout << "nonexistent branch … " << r << std::endl;
r = tree->SetBranchAddress(“fake_px”, fake_pxp);
std::cout << "nonexistent branch … " << r << std::endl;
r = tree->SetBranchAddress(“fake_px”, &fake_pxp);
std::cout << "nonexistent branch … " << r << std::endl;
}[/code]
Note: in the “tests” below you will see exactly which method gets called. I modified my “TTree.cxx” and “TChain.cxx” so that now every “SetBranchAddress” says that it got called (but I did not modify “TTree.h”, so templated methods will not be “verbose”).
First … “TTree” tests: [code]ALL should be FINE …
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Float_t … 0
p = 0x8ce8018
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Float_t … 0
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Float_t … 0
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Float_t … 0
ALL should FAIL …
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: The pointer type given “Int_t” (3) does not correspond to the type needed “Float_t” (5) by the branch: px
Int_t … -2
p = 0x8ce8018
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: The pointer type given “Int_t” (3) does not correspond to the type needed “Float_t” (5) by the branch: px
Int_t … -2
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: The pointer type given “Int_t” (3) does not correspond to the type needed “Float_t” (5) by the branch: px
Int_t … -2
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: The pointer type given “Int_t” (3) does not correspond to the type needed “Float_t” (5) by the branch: px
Int_t … -2
ALL should FAIL …
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
TString … 0
p = 0x8ce8018
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
TString … 0
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
TString … 0
ALL should FAIL …
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
TObjString … 0
p = 0x8ce8018
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
TObjString … 0
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
TObjString … 0
ALL should FAIL …
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5
p = 0xffffffff
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5
TTree::SetBranchAddress(const char*, void*, TBranch**, TClass*, EDataType, Bool_t)
Error in TNtuple::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5[/code] Note the following problems:
- As soon as a “real class” is involved (TString of TObjString), it happily returns 0 (should be -2 in all these crazy cases)!
- In case of a non-existent branch, the pointer “p” is left uninitialized (should be set to 0)!
The good news is that both, the interpreted code and the (ACLiC pre-)compiled code, behave the same.
Then … “TChain” tests: [code]ALL should be FINE …
TChain::SetBranchAddress(const char , void, TBranch**)
Float_t … 0
p = 0x937b280
TChain::SetBranchAddress(const char , void, TBranch**)
Float_t … 0
TChain::SetBranchAddress(const char , void, TBranch**)
Float_t … 0
TChain::SetBranchAddress(const char , void, TBranch**)
Float_t … 0
ALL should FAIL …
TChain::SetBranchAddress(const char , void, TBranch**)
Int_t … 0
p = 0x937b280
TChain::SetBranchAddress(const char , void, TBranch**)
Int_t … 0
TChain::SetBranchAddress(const char , void, TBranch**)
Int_t … 0
TChain::SetBranchAddress(const char , void, TBranch**)
Int_t … 0
ALL should FAIL …
TChain::SetBranchAddress(const char , void, TBranch**)
TString … 0
p = 0x937b280
TChain::SetBranchAddress(const char , void, TBranch**)
TString … 0
TChain::SetBranchAddress(const char , void, TBranch**)
TString … 0
ALL should FAIL …
TChain::SetBranchAddress(const char , void, TBranch**)
TObjString … 0
p = 0x937b280
TChain::SetBranchAddress(const char , void, TBranch**)
TObjString … 0
TChain::SetBranchAddress(const char , void, TBranch**)
TObjString … 0
ALL should FAIL …
TChain::SetBranchAddress(const char , void, TBranch**)
Error in TChain::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5
p = 0
TChain::SetBranchAddress(const char , void, TBranch**)
Error in TChain::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5
TChain::SetBranchAddress(const char , void, TBranch**)
Error in TChain::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5
TChain::SetBranchAddress(const char , void, TBranch**)
Error in TChain::SetBranchAddress: unknown branch -> fake_px
nonexistent branch … -5[/code]Note the following problems:
- It happily returns 0 for any type of pointer, if the requested branch exists!
(The good news is that it sets the pointer “p” to 0 in case of a non-existent branch.)
Again, both, the interpreted code and the (ACLiC pre-)compiled code, behave the same.