Strange symbol name in output of nm command
Asked Answered
O

3

11

I built a dynamic lib called InterfaceLayer.so. When I call:

> nm InterfaceLayer

As output, I get some symbols that look like:

00000e28  T _Z5startv

while I was expecting it to be "start", just as the name of the function I defined in the code.

Why does this happen?

Olin answered 17/5, 2011 at 19:28 Comment(0)
T
25

That's because of C++ name mangling

nm -C

demangles them.

To prevent name mangling,

  • use a C compiler (gcc, not g++), name your source file .c (not .cpp)
  • or declare extern "C":

.

my.h

  extern "C" 
  {
        void start();
        void finish();
  }

This will give them "C" linkage, meaning they can't be overloaded, cannot pass by reference, nothing c++ :)

Timepiece answered 17/5, 2011 at 19:30 Comment(3)
extern "C" does not mean that functions cannot pass by reference.Sestina
Suggestion to switch from C++ to C "to prevent name mangling" sounds like a suggestion to use guillotine to prevent dandruff. BTW, the OP never stated that they wanted to prevent it.Sestina
Agreed. Explaining that C++ is the source of the mangling still might add perspective. "Why does this happen" was explicitly in the question.Timepiece
E
3

Sounds like C++ name mangling.

Erigeron answered 17/5, 2011 at 19:31 Comment(2)
I often use c++filt when I need to demangle them: c++filt _Z5startvPerineum
nm myApp | c++filt; # Is exactly what I needed. I'm on OSX and XCode with it's warped GNU tool stack, and it doesn't support nm -C. Thanks @PerineumFlowerdeluce
F
2

As other answers have mentioned, this is likely becuase of C++ name mangling. If you want the symbol to be accessible by it's 'unmangled' name, and it's implemented in C++, you'll need to us extern "C" to tell the C++ compiler that it has a C linkage.

In the header that has the function prototype, you'll want something like:

#if defined(__cplusplus)
extern "C" {
#endif

// the prototype for start()...


#if defined(__cplusplus)
}
#endif

This will ensure that if the function is used by a C++ compiler, it'll get the extern "C" on the declaration, and that if it's used by a C module, it won't be confused by the extern "C" specifier.

You implementation in the .cpp file doesn't need that stuff if you include the header before the function definition. It'll use the linkage specification it saw from the previous declaration. However, I prefer to still decorate the function definition with extern "C" just to ensure that everything is in sync (note that in the .cpp file you don't need the #ifdef preprocessing stuff - it'll always be compiled as C++.

Fizz answered 17/5, 2011 at 19:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.