Hi all,
I have trouble with a strange situation.
The following code:
#include <iostream>
using namespace std;
float a;
int test(){
a=1.;
cout<<a<<endl;
return 0;
}
works when runned both as
root test.C
and compiled as
root test.C+
On the other end the following code:
#include <iostream>
using namespace std;
float step;
int test(){
step=1.;
cout<<step<<endl;
return 0;
}
works when runned as
root test.C
both NOT when compiled as
root test.C+
(it works if compiled with g++ after the inclusion of int main(){return test();})
Is step some kind of protected keyword? How so? The workaround is as simple as “don’t use a global variable called step”, but I’d like to understand better what is wrong.
Yes, this is the linker deciding to re-use the existing step symbol (from regex.h) for your float variable. This is actually worked around in the interpreter - which is why with root test.C is works. But as root test.C+ creates a shared library (test_C.so) and loads it into ROOT, the linker / dynamic loader decide what to do, and we have no means of interfering…
You can reproduce this outside of ROOT using:
// step_shlib.cxx:
float step;
int initMe() {
step = 42.;
}
int trigger = initMe();
// step_main.cxx
#include <dlfcn.h>
extern "C" int printf(const char*,...);
int main() {
dlopen("libstep_shlib.so", RTLD_NOW);
printf("%s\n", dlerror());
return 0;
}
That’s not the first time we meet it (see some examples below).
I can only repeat what had already been asked in one of these old “problem reports” … could you, please, prepare a list of “known” global identifier clashes.
These are different issues; only the pi case is the same.
The important part is that for interactive use (i.e. the pi case you linked!) this is fixed! What we cannot fix is Linux’s dynamic loader: if you create a shared library and load it into a program that uses the same symbol name already then bad things happen. Independently of ROOT. And that’s what this post here was about.
The others are redefinition errors, i.e. C++ syntax errors not linker errors. That’s because of using namespace std; - and here we at least issue a helpful error message that allows people to pick a different name. Given that I don’t find that list of “known bad names” terribly helpful - it’s basically “all names in namespace std::”.