name mangling link errors with mixed C and C++
Posted by peeterjoot on October 11, 2011
I’ve been scratching my head trying to figure out one last link error after I made some code changes. From the linker I got:
ld: 0711-317 ERROR: Undefined symbol: .ossCacheSysFunctionPointers
yet my symbol appeared to be there:
$ rm -rf .t $ mkdir .t $ cd .t $ ar -xX64 ../libSTdb2osse.a $ nm -X64 *.o | grep ossCacheSysFunctionPointers .ossCacheSysFunctionPointers U - .ossCacheSysFunctionPointers() T 1600 ossCacheSysFunctionPointers() D 2120 24 ossCacheSysFunctionPointers() d 1984 8
Do you spot the problem? I’ve got the symbol with C++ mangling, but referenced using a C prototype. This is much easier to see with name mangling disabled
$ nm -C -X64 *.o | grep ossCacheSysFunctionPointers .ossCacheSysFunctionPointers U - .ossCacheSysFunctionPointers__Fv T 1600 ossCacheSysFunctionPointers__Fv D 2120 24 ossCacheSysFunctionPointers__Fv d 1984 8
ie: my symbol is there with C++ mangling. That little () in the nm output was hard to spot today! Perhaps I should dig out my glasses?
the lesson to learn here, which I’ve “learned” a few times, apparently not well enough, is to not put prototypes in .C files. Put them in an appropriate header where all the files that include the header will see the same linkage. Of course this doesn’t help if the file that defines the function doesn’t include the function and ends up with a different linkage.
Bill Phu said
ok. I don’t completely follow that. What is the format of the output? I guess I don’t understand name mangling at all!
peeterjoot said
The line:
means that an undefined reference was found to the function. Also in the output was:
which means that the function was found in the Text segment (ie: the definition of the function was found). See how these are different. In the unmangled version we see:
which makes it more obvious. A C++ function with parameters with mangline v (void). This is AIX, and on that platform the parameter list mangling always starts with __F. Example:
/* u.C */ void f(const int v) { }For this function you see __Fi for function that has (int) parameter.
Bill Phu said
Hmm so is it looking for
.ossCacheSysFunctionPointers__Fv T
But only finding
ossCacheSysFunctionPointers__Fv D
?
peeterjoot said
No, it’s looking for ossCacheSysFunctionPointers, and only finding ossCacheSysFunctionPointers__Fv. I think that the D means that this function declared a static variable, so some part of it’s contribution to the shared library is in the Data segment.