[ROOT] Bug in CINT!?

From: Christian Holm Christensen (cholm@hehi03.nbi.dk)
Date: Tue Oct 31 2000 - 13:36:02 MET


Hi Masa and ROOT'ers, 

I believe I found a bug/feature in CINT, but it could also be me. 
Anyway, when I interpret the code, given below in Bugmain.C, I get the
following result:

  Processing BugMain.C...
  Addresses:  Element: 0x86dd458
    Data: 0x86dfba0
    Values:  0
  Addresses:  Element: 0x86dd498
    Data: 0x8707c48
    Values:  1
  Addresses:  Element: 0x86dd4c8
    Data: 0x86dd5b0
    Values:  2
  Addresses:  Element: 0x86dd4f8
    Data: 0x86dd5b0
    Values:  2
  Addresses:  Element: 0x86dd528
    Data: 0x86dd5b0
    Values:  10
  Addresses:  Element: 0x86dd558
    Data: 0x86dd5b0
    Values:  20

but when I compile BugMain.C I get: 

  Addresses:  Element: 0x842e140
    Data: 0xbffff5e8
    Values:  0 
  Addresses:  Element: 0x842e170
    Data: 0xbffff5e8
    Values:  1
  Addresses:  Element: 0x842e1a0
    Data: 0xbffff5e8
    Values:  2
  Addresses:  Element: 0x842e1d0
    Data: 0xbffff5e8
    Values:  0
  Addresses:  Element: 0x842e200
    Data: 0xbffff5e8
    Values:  10
  Addresses:  Element: 0x842e230
    Data: 0xbffff5e8
    Values:  20

which I believe is right. So I guess CINT is a bit too clever for it's
own good, not considering the scope of some variables, since it can
save time/space by (ANSI - erroneously) reusing some
variables. Someone must be wrong, and ofcourse it could be me, but
this inconsistency is - well - wrong. 

I'm using ROOT Version 2.25/03, CINT version 5.14.50, on a i386
(PIII), running Redhat Linux version 6.1.   

Here's the script/app source code:

  #ifndef __CINT__
  #include <TROOT.h>
  #include <iostream>
  #include "Bug.h"

  TROOT bugRoot("bugRoot", "Buggy ROOT");

  int 
  main (int argc, char** argv) 
  #endif 
  {
  #ifdef __CINT__
    gSystem->Load("libBug.so");
  #endif 

    Int_t i;
    BugContainer* cont1 = new BugContainer(3);
    BugContainer* cont2 = new BugContainer(3);
  
    for (i = 0; i < 3; i++) {
      BugElement* elem = new BugElement(i);
      cont1->AddElement(elem);
    }
    for (i = 0; i < 3; i++) {
      BugElement* elem = new BugElement(i * 10);
      cont2->AddElement(elem);
    }
  
    for (i = 0; i < 3; i++) {
      BugElement* elem = cont1->GetElement(i);
      BugData     data = elem->GetData();
      cout << "Addresses:  Element: " << elem << endl;
      cout << "  Data: " << &data << endl;
      cout << "  Values:  " << data.GetData() << endl;
    }
    for (i = 0; i < 3; i++) {
      BugElement* elem = cont2->GetElement(i);
      BugData     data = elem->GetData();
      cout << "Addresses:  Element: " << elem << endl;
      cout << "  Data: " << &data << endl;
      cout << "  Values:  " << data.GetData() << endl;
    }
  }

And the header for the classes used: 

  // -*- mode: c++ -*- 
  #ifndef CHOLM_Bug
  #define CHOLM_Bug
  #ifndef ROOT_TObject
  #include <TObject.h>
  #endif 
  #ifndef ROOT_TObjArray
  #include <TObjArray.h>
  #endif 
  
  
  class BugData : public TObject 
  {
  private:
    Int_t fData;
  public:
    BugData(Int_t i=0) : fData(i) {}
    
    Int_t GetData() const { return fData; }
    void  SetData(Int_t i) { fData = i; }
    
    ClassDef(BugData,1) // Data object 
  }
  ;
         
  class BugElement : public TObject 
  {
  private:
    BugData fData; // Internal member
  public:
    BugElement(Int_t i=0) : fData(i) {}
    BugData GetData(void) const { return fData; }
  
    ClassDef(BugElement,1) // Data element
  }
  ;
  
  class BugContainer : public TObject 
  {
  private:
    TObjArray *fElements;
  public:
    BugContainer(Int_t size=10) { fElements = new TObjArray(size); }
    
    void        AddElement(BugElement* e) { fElements->Add(e); }
    BugElement* GetElement(Int_t i) const { 
      return (BugElement*)fElements->At(i); }
  
    ClassDef(BugContainer,1) // Data element
  }
  ;
  
  #endif 

The link file:

  // -*- mode: c++ -*- 
  #pragma link off all globals;
  #pragma link off all functions;
  #pragma link off all classes;
  #pragma link C++ class BugData;
  #pragma link C++ class BugElement;
  #pragma link C++ class BugContainer;
  #endif 

The source file:

  #include "Bug.h"
  ClassImp(BugData);
  ClassImp(BugElement);
  ClassImp(BugContainer);

And a rather ugly Makefile 
  
  all:
	  rootcint -f BugCint.cxx -c Bug.h BugLinkDef.h 
	  g++ -c -Wall -g `root-config --cflags` BugCint.cxx 
	  g++ -c -Wall -g `root-config --cflags` Bug.cxx 
	  g++ -shared -Wl,-soname,libBug.so -o libBug.so Bug.o BugCint.o 
	  g++ `root-config --cflags --libs` \
		-Wl,-rpath,./ -L./ -lBug BugMain.C -o bug 
  clean:
	  rm -f *.o bug *.so *~ *Cint.* 

Yours, 

Christian  -----------------------------------------------------------
Holm Christensen                             Phone:  (+45) 35 35 96 91 
  Sankt Hansgade 23, 1. th.                  Office: (+45) 353  25 305 
  DK-2200 Copenhagen N                       Web:    www.nbi.dk/~cholm    
  Denmark                                    Email:       cholm@nbi.dk



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:36 MET