Hi Murik and fellow Rooters, I just had a similar problem and after days of hacking and reading the C++ standard carefully again I found the following that might be your basic problem (and which has nothing to do with ClassDef() macros, but with interpreted versus compiled code!). In C++ the size of a class, struct and union is *NOT* necessarily equal the sum of bytes of its members!! That means a C++ compiler/interpreter is allowed to assign any size it wants to following struct (same for class and union) struct Test_t { Char_t c; Short_t i; } testStruct; Naively (and rightly so) you would expect to get a sizeof(testStruct) = 3. This you will get e.g. with the gcc compiler and default flags. HOWEVER a compiler is free to assign ANY size it wants (in practice they often align the struct boundaries on multples of 8 bytes for efficiency reason - so does e.g. the Microsoft VC++ compiler by default), i.e. they "pad" the testStruct (of naive size 3) with 1 or even 5 bytes!! Therefore an array of structs, e.g. Test_t testArray[10]; will be 80 bytes long instead of 30 (with 5 byte gaps between each struct element). This is exactly the case with the CINT interpreter. On my (WinNT and Sun/Solaris) versions CINT assigns 8 bytes to above struct: root [0] struct Test_t { Char_t c; Short_t i;} testStruct root [1] sizeof(testStruct) (int)8 root [2] Test_t testArray[10] root [3] sizeof(testArray) (int)80 BOTTOM LINE: You CANNOT assume sizeof(struct/class/union) = sum of member sizes!!! If code relies on this (because it happens to work on one compiler) it is certainly not portable. You *CANNOT* EQUIVALENCE/union a C++ class/struct with a continuos storage (fortran or C/C++) array in a portable manner! (I fell into this pitfall too). It is ANSI-C++'s fault not ROOT/CINT's (the latter apparently chooses the most efficent 8-byte alignment...). If you want to read a fortran array into a class you have to copy member-by-member from the appropriate array elements in a loop. So far my experience with that alignment ambiguity problem. Now a question to CINT experts: Most compilers have a switch to turn "struct/class/union-alignments" on/off or to specific value (2,4, 8). I haven't found any similar option for CINT. Is there a switch for CINT ???? Also, is there a way to define a certain aligment choice for a specific struct and another one for the next struct/class (I am thinking/hoping of some #pragma switch) ?? Even if not required by the C++ standard, it would be nice to have... Thanks in advance Peter ----- Original Message ----- From: Maurik Holtrop <maurik.holtrop@unh.edu> To: roottalk <roottalk@hpsalo.cern.ch> Sent: Thursday, May 20, 1999 11:47 AM Subject: ClassDef() Increases class size? > Hello Root, > > I seem to be running into a problem with ClassDef (and ClassImp) increasing > the size of my class's storage area by about 4 bytes. I am *not* deriving > from TObject, so the extra bytes are not from there. > Is there a way around this which will still give me all the nice features > (streamer, showmember etc) of ROOT but keep my class the exact same size as > the data members I defined? > > The reason that the extra bytes are a problem is because I am setting > pointers into an already existing array with data (which is created by a > FORTRAN package called BOS), in order to read it's contends. The extra bytes > causes the next pointer to be 4 bytes off. > > Maurik > > > -------------------------------------------------------------------------- ------- > > Sample code: > > The following code will have a "sizeof()" of 56 instead of the expected 52: > > class TPARTData { > public: > Int_t pid; /* particle id > (GEANT) */ > Float_t x; /* vector3_t vert; Vertex position > {x,y,z} */ > Float_t y; /* > y */ > Float_t z; /* > z */ > Float_t e; /* vector4_t p; > Energy */ > Float_t px; /* momentum > {x,y,z} */ > Float_t py; /* > py */ > Float_t pz; /* > pz */ > Float_t q; /* > charge */ > Int_t trkid; /* index to TBID bank, counting from > 1 */ > Float_t qpid; /* quality factor for the > pid */ > Float_t qtrk; /* quality factor for the > trk */ > Int_t flags; /* set of flags defining track (ie, > BEAM) */ > > ClassDef(TPARTData,1) > > }; > >
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:33 MET