Bug in rootcling?


_ROOT Version:6.20 / 6.22
_Platform:CentOS8.2
_Compiler:gcc8.3.1


Very simple bit of code creating a class

#include "TObject.h"
#include "TVector3.h"

class testData : public TObject  {

 public:
	testData() { }; 
	virtual ~testData() { };

 private :
	std::vector<TVector3> fDirection[ 255 ];

	ClassDef( testData, 1 );

};

If I try to compile the dictionary created by rootcling from the above with either 6.20 or 6.22 with gcc8 I get loads of errors like :

Dict.C: In member function ‘virtual void testData::Streamer(TBuffer&)’:
Dict.C:125:27: error: expected identifier before numeric constant
          vector<TVector3>[255] &R__stl =  fDirection[R__l];
                           ^~~
Dict.C:125:27: error: expected ‘]’ before numeric constant
          vector<TVector3>[255] &R__stl =  fDirection[R__l];
                           ^~~
                           ]
Dict.C:125:26: warning: structured bindings only available with -std=c++17 or -std=gnu++17
          vector<TVector3>[255] &R__stl =  fDirection[R__l];
                          ^
Dict.C:125:26: error: structured binding declaration cannot have type ‘std::vector<TVector3>’
Dict.C:125:26: note: type must be cv-qualified ‘auto’ or reference to cv-qualified ‘auto’
Dict.C:125:26: error: empty structured binding declaration
Dict.C:125:32: error: expected initializer before ‘&’ token
          vector<TVector3>[255] &R__stl =  fDirection[R__l];
                                ^
.....

The same code compiles fine with ROOT5 on say CentOS6.10 ( gcc4.4.7 ) . The Dict.C file is attached below ( I hope … )

Dict.C (10.0 KB)

Do you really mean to create an array of 255 distinct std::vector objects (each containing a variable number of TVector3 objects) ?

If this is the case, consider using:

std::vector<std::vector<TVector3>> { 255 };  // Initialization via the curly bracket to reserve slot for 255 vector of TVector3

We want a vector with 255 individual TVector3’s in it - yes . gcc accepts the syntax and does the right thing ( confirmed in gdb ) . ROOT5 creates a dictionary that compiles . ROOT6 also makes a dictionary without errors but gcc won’t compile it. So to me it looks like cling is mangling / misinterpreting the construct ( but cint doesn’t )

                      peter

Two additional comments :

  1. If I compare the code produced by cling ( ROOT 6 ) to that made by cint ( ROOT5 ) the only difference is the “extra” [255]" in say
vector<TVector3>[255] &R__stl =  fDirection[R__l];
  1. Removing any “[255]” by hand from the cling output makes things work again with ROOT6

So - this looks like a bug in cling

This is not what the code provided does. It creates 255 vectors which an unspecified number of TVector3 inside each of those vectors. You probably meant to use:

std::vector<TVector3> { 255 };  

which create a single vector with 255 slots for TVector3 objects.

ROOT5 creates a dictionary that compiles .

It does compiles but it does not “work”. The result is that only the first of the 255 vectors is stored.

More importantly I noticed that your dictionary is using the “very old” I/O streaming technique (that generate a Streamer function). That 2 main weakness of this old technique is poor/broken support for STL container and no support for splitting or I/O customization rules.

Switching to the new StreamerInfo based I/O streaming technique will remove that code from the dictionary entirely. To do so, in your LinkDef file add a trailing + to the dictionary request:

#pragma link C++ class testData+;

Cheers,
Philippe.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.