Rootcint problems using qsort

Hello,

I’m trying to implement a class (which inherits from TNamed) which has a member function that calls qsort to sort an array of type double. I need to implement a comparator function for this to work; however, when I try to make the comparator a member function of my class I get the compiler error:

g++ -g -Wno-conversion -fPIC -D_REENTRANT -I/Users/mschmid7/root/include -I. -c -o TNMLHisto.o TNMLHisto.cc
TNMLHisto.cc: In member function ‘bool TNMLHisto::optimize(const double*, int, int, double, double, double*, int&)’:
TNMLHisto.cc:398: error: argument of type ‘int (TNMLHisto::)(const void*, const void*)’ does not match ‘int ()(const void, const void*)’

which makes sense, since qsort needs a pointer to a function of type int. So, I move the function definition outside of my class, and I find that I now have a rootcint-related error:

g++ -g -Wno-conversion -fPIC -D_REENTRANT -I/Users/mschmid7/root/include -I. -c -o TNMLHisto.o TNMLHisto.cc
Generating dictionary …
rootcint -f TNMLHistoDict.C -c TNMLHisto.hh LinkDef.hh
g++ -g -Wno-conversion -fPIC -D_REENTRANT -I/Users/mschmid7/root/include -I. -c -o TNMLHistoDict.o TNMLHistoDict.C
Linking …
g++ -dynamiclib -o libTNMLHisto.so TNMLHisto.o TNMLHistoDict.o -L/Users/mschmid7/root/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lfreetype -lpthread -lm -ldl -lMinuit -lRooFitCore -lRooFit
ld: multiple definitions of symbol _Z13double_comparPKvS0
TNMLHisto.o definition of _Z13double_comparPKvS0 in section (__TEXT,__text)
TNMLHistoDict.o definition of _Z13double_comparPKvS0 in section (__TEXT,__text)
ld: multiple definitions of symbol _Z13double_comparPKvS0.eh
TNMLHisto.o definition of absolute _Z13double_comparPKvS0.eh (value 0x0)
TNMLHistoDict.o definition of absolute _Z13double_comparPKvS0.eh (value 0x0)
/usr/bin/libtool: internal link edit command failed
make: *** [libTNMLHisto.so] Error 1

I’m guessing this has to do with my LinkDef file. I’ve tried linking the function: double_compar using the statement:

#pragma link C++ function double_compar;

but this doesn’t have any effect. Any suggestions? This seems like it would be a common problem to anyone trying to use qsort.

Thanks,
Michael

[quote=“ElMickerino”]Hello,

I’m trying to implement a class (which inherits from TNamed) which has a member function that calls qsort to sort an array of type double. I need to implement a comparator function for this to work; however, when I try to make the comparator a member function of my class I get the compiler error:

g++ -g -Wno-conversion -fPIC -D_REENTRANT -I/Users/mschmid7/root/include -I. -c -o TNMLHisto.o TNMLHisto.cc
TNMLHisto.cc: In member function ‘bool TNMLHisto::optimize(const double*, int, int, double, double, double*, int&)’:
TNMLHisto.cc:398: error: argument of type ‘int (TNMLHisto::)(const void*, const void*)’ does not match ‘int ()(const void, const void*)’

which makes sense, since qsort needs a pointer to a function of type int. So, I move the function definition outside of my class, and I find that I now have a rootcint-related error:

g++ -g -Wno-conversion -fPIC -D_REENTRANT -I/Users/mschmid7/root/include -I. -c -o TNMLHisto.o TNMLHisto.cc
Generating dictionary …
rootcint -f TNMLHistoDict.C -c TNMLHisto.hh LinkDef.hh
g++ -g -Wno-conversion -fPIC -D_REENTRANT -I/Users/mschmid7/root/include -I. -c -o TNMLHistoDict.o TNMLHistoDict.C
Linking …
g++ -dynamiclib -o libTNMLHisto.so TNMLHisto.o TNMLHistoDict.o -L/Users/mschmid7/root/lib -lCore -lCint -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lTree -lRint -lPostscript -lMatrix -lPhysics -lfreetype -lpthread -lm -ldl -lMinuit -lRooFitCore -lRooFit
ld: multiple definitions of symbol _Z13double_comparPKvS0
TNMLHisto.o definition of _Z13double_comparPKvS0 in section (__TEXT,__text)
TNMLHistoDict.o definition of _Z13double_comparPKvS0 in section (__TEXT,__text)
ld: multiple definitions of symbol _Z13double_comparPKvS0.eh
TNMLHisto.o definition of absolute _Z13double_comparPKvS0.eh (value 0x0)
TNMLHistoDict.o definition of absolute _Z13double_comparPKvS0.eh (value 0x0)
/usr/bin/libtool: internal link edit command failed
make: *** [libTNMLHisto.so] Error 1

I’m guessing this has to do with my LinkDef file. I’ve tried linking the function: double_compar using the statement:

#pragma link C++ function double_compar;

but this doesn’t have any effect. Any suggestions? This seems like it would be a common problem to anyone trying to use qsort.

Thanks,
Michael[/quote]
I don’t see your code, but I can guess that you need to make your member function to be a static method and then pass (&TNMLHisto::comp) to a qsort.

BTW, what is wrong with std::sort? 8)
From my side I would recommend to use C++ instead of C (qsort). C++ has more than enough machinery to implement very complex tasks :slight_smile:
With std::sort you could use bind or bind1st and mem_fun from std, std::tr1 or BOOST to pass a method of the class (which could be not a static ones). I would recommend the std::tr1::bind (which is inherited from boost::bind) - a very powerful one!

[quote]I’m guessing this has to do with my LinkDef file. I’ve tried linking the function: double_compar using the statement: [/quote]Nope, most likely you forgot the keyword ‘inline’ in front of the implementation of your function.

Anyway, I agree with Anar that you ought to look into using std::sort :slight_smile:

Cheers,
Philippe

Great, thanks for your help!

-Michael