Uploaded image for project: 'ROOT'
  1. ROOT
  2. ROOT-9114

garbage code generated in dictionary file for typedefs of templates



    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Medium
    • Resolution: Unresolved
    • Affects Version/s: 6.11/02
    • Fix Version/s: 6.14/00, 6.16/00
    • Component/s: Cling
    • Labels:
    • Environment:

      Linux (All)


      Start with the following header and linkdef.h, then generate + compile a dictionary:

      $ cat AAA.h
      #ifndef AAA_H
      #define AAA_H
      template<typename Enum> class QFlags {};
      enum Option { };
      typedef QFlags<Option> Options;
      $ cat AAA_linkdef.h
      #pragma link C++ typedef Options;
      $ rootcling -f AAADict.cxx AAA.h AAA_linkdef.h
      $ g++ `root-config --cflags` -fPIC AAADict.cxx -shared -o libAAADict.so

      Then try to use this from the ROOT prompt:

      $ root -l -b
      root [0] gSystem->Load("libAAADict.so")
      (int) 0
      root [1] Options a;
      ROOT_prompt_1:1:9: error: implicit instantiation of undefined template 'QFlags<Option>'
      Options a;
      AAADict dictionary forward declarations' payload:6:83: note: template is declared here
      template <typename Enum> class __attribute__((annotate("$clingAutoload$AAA.h")))  QFlags;
      root [2]

      The odd bit of course being that the template in the original header is fully defined. The problem is with the definition in the fwdDeclCode section in the dictionary, which only forward declares the template ...

      But next, the following should be legal C++11, but fails:

      root [0] gSystem->Load("libAAADict.so")
       (int) 0
       root [1] #include "AAA.h"
       In file included from ROOT_prompt_1:1:
       ./AAA.h:6:24: error: typedef redefinition with different types ('QFlags<Option>' vs 'QFlags<Option>')
       typedef QFlags<Option> Options;
       AAADict dictionary forward declarations' payload:8:24: note: previous definition is here
       typedef QFlags<Option> Options __attribute__((annotate("$clingAutoload$AAA.h"))) ;
       root [2]

      The two typedefs aren't any different, so that should have been legal.

      Then, I can, of course, edit the generated dict file, but if I do, the typedef becomes unknown.

      Finally, I can simply #include the header and that, happily, all works ...

      I'm going to try whether I can add the full template definition in the forward declaration, but I doubt that that is enough, b/c a forward declaration only, with the full definition loaded later, should be perfectly valid C++ (and is in fact closer to what actually happens in KDE).




            axel Axel Naumann
            wlav Wim Lavrijsen
            0 Vote for this issue
            3 Start watching this issue