C++ preprocessor problem

It seems to me that the C++ preprocessor in ROOT misbehaves.

Download the “VTK-9.0.3/Common/Core/vtkAutoInit.h” file.

Create two dummy files: touch vtkDebugLeaksManager.h vtkTimeStamp.h

Then try:

root [0] void vtkRenderingOpenGL2_AutoInit_Construct() {};
root [1] #include "vtkAutoInit.h"
root [2] VTK_MODULE_INIT(vtkRenderingOpenGL2);
ROOT_prompt_2:1:1: error: namespaces can only be defined in global or namespace scope
VTK_MODULE_INIT(vtkRenderingOpenGL2);
^
./vtkAutoInit.h:88:3: note: expanded from macro 'VTK_MODULE_INIT'
  {                                                                                                \
  ^
root [3] 

ROOT has a hard time determining whether VTK_MODULE_INIT(vtkRenderingOpenGL2); is declaring something, or whether it’s expression to be evaluated. This will fix it:

.rawInput
VTK_MODULE_INIT(vtkRenderingOpenGL2);
.rawInput

(And that’s exactly what .rawInput was invented for, to disambiguate decls from exprs.)

Thanks for checking.

I guess the problem is that I would need to “inject” a couple of such “VTK_MODULE_INIT(...)” lines from inside of the interpreted “rootlogin.C” (using something like “gInterpreter->ProcessLine(...)” or “gInterpreter->LoadText(...)”).

Actually, also with your fix, it breaks:

root [0] void vtkRenderingOpenGL2_AutoInit_Construct() {};
root [1] #include "vtkAutoInit.h"
root [2] .rawInput
Using raw input
root [3] VTK_MODULE_INIT(vtkRenderingOpenGL2);
ROOT_prompt_3:1:1: error: call to 'vtkRenderingOpenGL2_AutoInit_Construct' is ambiguous
VTK_MODULE_INIT(vtkRenderingOpenGL2);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./vtkAutoInit.h:92:26: note: expanded from macro 'VTK_MODULE_INIT'
      M##_ModuleInit() { VTK_AUTOINIT_CONSTRUCT(M) }                                               \
                         ^~~~~~~~~~~~~~~~~~~~~~~~~
./vtkAutoInit.h:71:35: note: expanded from macro 'VTK_AUTOINIT_CONSTRUCT'
#define VTK_AUTOINIT_CONSTRUCT(M) M##_AutoInit_Construct();
                                  ^~~~~~~~~~~~~~~~~~~~~~
<scratch space>:5:1: note: expanded from here
vtkRenderingOpenGL2_AutoInit_Construct
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ROOT_prompt_0:1:6: note: candidate function
void vtkRenderingOpenGL2_AutoInit_Construct() {};
     ^
ROOT_prompt_3:1:1: note: candidate function
VTK_MODULE_INIT(vtkRenderingOpenGL2);
^
./vtkAutoInit.h:87:3: note: expanded from macro 'VTK_MODULE_INIT'
  VTK_AUTOINIT_DECLARE(M) namespace                                                                \
  ^
./vtkAutoInit.h:52:38: note: expanded from macro 'VTK_AUTOINIT_DECLARE'
#define VTK_AUTOINIT_DECLARE(M) void M##_AutoInit_Construct();
                                     ^
<scratch space>:2:1: note: expanded from here
vtkRenderingOpenGL2_AutoInit_Construct
^
root [4] .rawInput
Not using raw input
root [5] 

If they are fixed, make them a header that you #include. Else you can use gInterpreter->Declare("code") which will implicitly be in the “rawInput” mode. Please provide all declarations like that: the issue with the ambiguous declaration stems from a mechanism that allows cling to re-declare entities automatically. Declaring everything “in one go” will solve that.

Does that help?

Thanks again.

It seems this works (suits my needs well):

root [0] #include "vtkAutoInit.h"
root [1] gInterpreter->Declare("void vtkRenderingOpenGL2_AutoInit_Construct() {cout << \"blah blah\" << endl;}; VTK_MODULE_INIT(vtkRenderingOpenGL2);")
blah blah
(bool) true
root [2] 

Creating a separate “#include” file also works.

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