root icon indicating copy to clipboard operation
root copied to clipboard

[IO] `TCling::GenerateDictionary` is broken for `RVec<CustomType>`

Open eguiraud opened this issue 4 years ago • 4 comments

  • [X] Checked for duplicates

Describe the bug

As far as I understand, this should work:

#ifndef TWOINTS
#define TWOINTS
struct TwoInts {
   int a, b;
};
#endif
#include <ROOT/RDataFrame.hxx>
#include <TError.h>
#include <TInterpreter.h>
#include <TKey.h>

#include "TwoInts.h"

int main() {
  gInterpreter->GenerateDictionary("TwoInts;ROOT::VecOps::RVec<TwoInts>",
                                   "ROOT/RVec.hxx;TwoInts.h");

  TFile f("f.root", "recreate");
  auto *cl = TClass::GetClass("ROOT::VecOps::RVec<TwoInts>");
  R__ASSERT(cl != nullptr);
  ROOT::RVec<TwoInts> v{{1, 2}, {3, 4}};
  f.WriteObjectAny(&v, cl, "v");
  f.Close();
  TFile in_f("f.root");
  auto *k = in_f.GetKey("v");
  auto *obj = static_cast<ROOT::RVec<TwoInts> *>(k->ReadObjectAny(cl));
  R__ASSERT(obj != nullptr);
  auto &in_v = *obj;
  R__ASSERT(in_v[0].a == 1 && in_v[0].b == 2 && in_v[1].a == 3 &&
            in_v[1].b == 4);

  return 0;
}

But instead produces:

g++ -g -Wall -Wextra -Wpedantic -o "repro" "repro.cpp" $(root-config --cflags --libs)
~/S/w/rootcling_rvec ./repro
/home/blue/Scratchpad/work/rootcling_rvec/AutoDict_TwoInts_2251615068_cxx_ACLiC_dict.cxx:55:61: error: expected ‘)’ before ‘::’ token
   55 |    static TGenericClassInfo *GenerateInitInstanceLocal(const ::*)
      |                                                       ~     ^~~
      |                                                             )

because the autogenerated dictionary code is broken (see the invalid (const ::*).

Setup

ROOT master @ 9f1902c1 . I would not even attempt this with v6.24 or earlier because I/O of RVecs is not well-supported there.

Additional context

https://github.com/root-project/root/blob/9f1902c1d898ec615244f547c0683d0f10820da8/core/metacling/src/TCling.cxx#L742-L745

This is definitely part of the problem: RVec should be treated like an STL class. Axel also pointed out the suspicious:

https://github.com/root-project/root/blob/9f1902c1d898ec615244f547c0683d0f10820da8/core/metacling/src/TCling.cxx#L786-L796

eguiraud avatar Mar 26 '21 10:03 eguiraud

A more minimal reproducer that catches at least some of the problems:

// LinkDef.h
#include <ROOT/RVec.hxx>
#include "TwoInts.h"
#ifdef __CLING__
#pragma link C++ class ROOT::VecOps::RVec<TwoInts>+;
#pragma link C++ class ROOT::VecOps::RVec<TwoInts>::*+;
#endif
// TwoInts.h
#ifndef TWOINTS
#define TWOINTS
struct TwoInts {
   int a, b;
};
#endif

and rootcling "twoints_dict.cxx" LinkDef.h produces invalid C++ in twoints_dict.cxx.

The line #pragma link C++ class ROOT::VecOps::RVec<TwoInts>::*+; is required to trigger the problematic behavior (and TCling::GenerateDictionary puts it in the auto-dicts).

eguiraud avatar Mar 26 '21 11:03 eguiraud

This is still a problem in v6.26.

eguiraud avatar Mar 17 '22 18:03 eguiraud

I was just hit by this again after forgetting about it again :smile: ping @pcanal @Axel-Naumann :grimacing:

eguiraud avatar May 26 '22 12:05 eguiraud

@devajithvs @vgvassilev do you have a hint?

dpiparo avatar May 17 '24 07:05 dpiparo