RE: Problem reading branches of structs

From: Rene Brun <brun_at_pcroot.cern.ch>
Date: Fri, 29 Apr 2005 22:51:39 +0200 (MEST)


Hi Andrea,

Your example is totally different of your first example. It mixes basic types of different sizes. In this case, you will get alignment problems. You must go via a class instead of a struct to get a correct support in both C++ and CINT. Note that although your example works with C++, it will be very inefficient because the compiler will have to align your double anyhow.

Rene Brun

On Wed,
27 Apr
2005, Andrea Bocci wrote:

> > Andrea,
> >
> > I do not understand your argument that:
> > "gcc keeps the struct fields aligned to 4 bytes boundary"
> > This is impossible with your struct.
>
> Well, in the comiled code, sizeof(bTagInfo) is 68, while in ROOT/CINT it is 72. So, different packing and allignement is applied.
>
> > Could you replace
> >
> > tree->SetBranchAddress ("bTagInfo", &info);
> > by
> > tree->SetBranchAddress ("bTagInfo", &info.jet_E);
>
> But this would completely de-allign (either of 4 or 8 bytes) the struct in memory with the one in the root file.
>
> > Note that we keep discouraging users to use structs instead
> > of classes. With a class and its dictionary, you will simplify
> > your interface when defining the branch: no need to specify
> > the names of the data members since they are already known
> > by the dictionary, and in addition you will get support
> > for correct alignment of members in the class.
>
> I know, and I usually do it, but I wanted a simpler solution, without the need of an external (however simple) library.
> I guess that saying that this is not supported is an acceptable solution - I can either compile all my applications (I usually do it), or use a class with a dictionary. Anyway:
>
> > if you do not solve your problem, please send the shortest
> > possible system reproduding it.
>
> here is a simple tet case, which show the same behaviour.
> Again, sizof(XData) is 12 with gcc, but 16 with root.
>
> --- XData.h -------------------------------------------------
> #ifndef XData_h
> #define XData_h
>
> struct XData {
> unsigned int an_int;
> double a_double;
> };
>
> #endif // XData_h
> -------------------------------------------------------------
>
> --- write.cc ------------------------------------------------
> #include <TFile.h>
> #include <TTree.h>
>
> #include "XData.h"
>
> void write (void) {
> TFile* file = new TFile("test.root", "RECREATE");
> TTree* tree = new TTree("Test", "Test tree for a simple structure");
>
> XData data;
> tree->Branch("XData", &data, "an_int/i:a_double/D");
>
> for (unsigned int i=0; i < 10; i++) {
> data.an_int = i;
> data.a_double = i;
> tree->Fill();
> }
> tree->Write();
> file->Close();
> }
>
> int main (int argc, const char** argv) {
> write();
> return 0;
> }
> -------------------------------------------------------------
>
> and
>
> --- read.cc -------------------------------------------------
> #include <iostream>
> using namespace std;
>
> #include <TFile.h>
> #include <TTree.h>
>
> #include "XData.h"
>
> void read (void) {
> TFile* file = new TFile("test.root");
> TTree* tree = (TTree*) file->Get("Test");
>
> XData data;
> tree->SetBranchAddress("XData", &data);
>
> for (unsigned int i=0; i < 10; i++) {
> tree->GetEvent(i);7
> cout << data.an_int << '\t' << data.a_double << endl;
> }
> file->Close();
> }
>
> int main (int argc, const char** argv) {
> read();
> return 0;
> }
> -------------------------------------------------------------
>
> compiled with
> g++ -O2 $(root-config --cflags --libs) write.cc -o write
> g++ -O2 $(root-config --cflags --libs) read.cc -o read
> using GCC 3.2.3 and ROOT 3.10/02 (I've tried ROOT 4.x, same behaviour).
>
> If I do:
> ./write
> ./read
>
> I get:
> 0 0
> 1 1
> 2 2
> 3 3
> 4 4
> 5 5
> 6 6
> 7 7
> 8 8
> 9 9
>
>
> If I do:
> ./write
> root read.cc
>
> I get:
> Processing read.cc...
> 0 3.39519e-313
> 1 3.44819e-313
> 2 3.44824e-313
> 3 3.44827e-313
> 4 3.44829e-313
> 5 3.44831e-313
> 6 3.44832e-313
> 7 3.44833e-313
> 8 3.44835e-313
> 9 3.44835e-313
>
> which doesn't look correct...
>
> I get something similar if I do:
> root write.cc read.cc
>
> While with:
> root write.cc
> ./read
>
> I get:
> Processing write.cc...
> 0 0
> 1 0
> 2 0
> 3 0
> 4 0
> 5 0
> 6 0
> 7 0
> 8 0
> 9 0
>
> (prompt lines removed, of course).
>
> Thanks for your time and replies !
>
> .Andrea.
>
>
Received on Fri Apr 29 2005 - 22:51:45 MEST

This archive was generated by hypermail 2.2.0 : Tue Jan 02 2007 - 14:45:07 MET