I tried many things and root keeps crashing whenever I invoke a function that takes a pointer to a function as parameter from the interpreter command line. When I put the same call inside a compiled function (below its the TEST_xx functions) it works as expected.
Here is a simple working example that reproduces the crash:
#include <iostream>
// 1 - passing a "int * (int,int)" pointer
int MyAdd(int a,int b){
cout << "MyAdd" << endl;
return a+b;
}
int MyMult(int a,int b){
cout << "MyMult" << endl;
return a*b;
}
void MyCalc(int a,int b,int (*op)(int,int)){
cout << "MyCalc" << endl;
int c = (*op)(a,b);
cout << a << " " << b << " " << c << endl;
}
void TEST_MyCalc(){
MyCalc(1,2,MyAdd);
MyCalc(1,2,MyMult);
}
// a) root[] TEST_MyCalc()
// works as expected
// b) root[] MyCalc(1,2,MyAdd)
// prints "MyCalc" and "MyAdd" and then crashes
// 2 - simpler: passing a "void * ()" pointer
void coutSomething(){cout << "Something" << endl;}
void coutSomethingelse(){cout << "Somethingelse" << endl;}
void MyCout(void (*coutFunc)()){(*coutFunc)();}
void TEST_MyCout(){
MyCout(coutSomething);
MyCout(coutSomethingelse);
}
// a) root[] TEST_MyCout()
// works as expected
// b) root[] MyCout(coutSomething)
// prints "Something" and then crahses (same as before)
// 3
// root[] MyAdd
// tells me its a "const int * (int,int)"
// so lets try this...
void MyConstCalc(int a,int b,const int (*op)(int,int)){
int c = (*op)(a,b);
cout << a << " " << b << " " << c << endl;
}
void TEST_MyConstCalc(){
//MyConstCalc(1,2,MyAdd); <- does not compile
//MyConstCalc(1,2,MyMult); <- does not compile
}
// a) compiler complains that
// error C2664: 'MyConstCalc' : cannot convert parameter 3
// from 'int (__cdecl *)(int,int)' to 'const int (__cdecl *)(int,int)'
// b) root[] MyConstCalc(1,2,MyAdd)
// prints "MyAdd" and then crashes (same as before)
// 4
// maybe the const refers to the pointer and not to the return value...
// nevertheless, lets try this...
const int MyConstAdd(int a,int b){
cout << "MyAdd" << endl;
return a+b;
}
void TEST_MyConstCalc2(){
MyConstCalc(1,2,MyConstAdd);
}
// a) root[] TEST_MyConstCalc2()
// works as expected
// b) root[] MyConstCalc(1,1,MyConstAdd)
// prints "MyAdd" and then crashes (same as before)
// 5 most simple example
void MyVoid(){}
void MyVoidCaller(void (*f)()){
cout << "before" << endl;
(*f)();
cout << "after" << endl;
}
void TEST_MyVoidCaller(){
MyVoidCaller(MyVoid);
}
// a) root[] TEST_MyVoidCaller()
// works as expected
// b) root[] MyVoidCaller(MyVoid)
// prints "before" and "after" and then crashes
// this is different from before!
// now also the cout after the function call (via pointer) is printed
// 6
// does the "cout << c ..." create problems?
// try this...
void MyConstCalc2(int a,int b,const int (*op)(int,int)){
int c = (*op)(a,b);
cout << "done" << endl;
}
// root[] MyConstCalc2(1,2,MyConstAdd)
// prints "MyAdd" and then crashes (again same as before)
// root[] MyConstCalc(1,2,MyAdd)
// ...same :(
I always use “.L filename.c++” to compile and load the code and then I invoke the functions as stated in the comments.
It is basically always the same behaviour, but I put all different variants I tried, because in one case (1b) the cout after the function call (via pointer and from the interpreter) does not appear on the screen while in a different case (5b) it does appear on the screen.
Seems like the function call in this case (5b) is done without problems but for some reason root still crashes (actually it might also be that in this case the compiler realizes that “MyVoid()” does not do anything at all and skips the call).
I guess cout is not the most reliable option for debugging, but still I would expect it to behave the same in all cases.
All other posts on this topic I found were about using a pointer to an interpreted function in compiled code or something else that did not really help me. Now I don’t really know where to look further.
EDIT: I was just reading about the “Position independent Code” issue. I forgot to mention that I am working on windows, compiling with cl.exe. I didnt fully understand the PIC story, but even when I compile the code in linux (there the compiler takes the “-fPIC” flag to create position independent code) root keeps crashing (with a segfault).