20

How can I avoid name mangling in C++?

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141
n00ki3
  • 14,529
  • 18
  • 56
  • 65

5 Answers5

31

You can't. It's built into compilers to allow you overloading functions and to have functions with the same name in different classes and such stuff. But you can write functions that are mangled like C functions. Those can be called from C code. But those can't be overloaded and can't be called by "normal" C++ function pointers:

extern "C" void foo() {

}

The above function will be mangled like C functions for your compiler. That may include no change at all to the name, or some changes like a leading "_" in front of it or so.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 1
    Just a minor nit: Such functions certainly can be called from C++ function pointers: extern "C" void foo() { printf("foo\n"); } int main() { void (*f)(); f = foo; f(); } – Greg Hewgill Feb 07 '09 at 23:03
  • 4
    Pax, C compilers may mangle too. gcc for example has the "-fleading-underscore" option. i remember some guy told me macosx mangles its C names with an underscore. (i don't own macosx so i can't check :)). – Johannes Schaub - litb Feb 08 '09 at 00:09
  • 3
    Greg, it will work generally, but it's not right. the function pointer must be a pointer that points to a function with C linkage. extern "C" typedef void funt(); int main() { funt * f = foo; f(); } note, two function types are different if they have diff linkage - even if they are otherwise not. – Johannes Schaub - litb Feb 08 '09 at 00:13
  • C names are not mangled. Mangling is the term used to encode type information into the function name. Adding the '_' to the front is common and an artifact of the linker (not know as mangling). – Martin York Feb 08 '09 at 12:27
  • 2
    No matter whether you call it mangling or name decoration, the fact remains that __stdcall C functions on MSVC get renamed from "func" to "_func@12" or similar. More info here: http://msdn.microsoft.com/en-us/library/zxk0tw93(VS.71).aspx – bk1e Feb 08 '09 at 18:05
  • 3
    Martin York. it doesn't matter how you call it. mangling is one term, decoration is another. both change the name that is used in the object file. wikipedia has an article about it (well, in some parts, it contradicts against itself..., but it contains the decoration stuff). i agree with bk1e – Johannes Schaub - litb Feb 08 '09 at 21:01
18

Other way:

Controlling Names Used in Assembler Code (gcc spec.)

You can specify the name to be used in the assembler code for a C function or variable by writing the asm (or __asm__) keyword after the declarator. It is up to you to make sure that the assembler names you choose do not conflict with any other assembler symbols, or reference registers.

To specify the assembler name for functions, write a declaration for the function before its definition and put asm there, like this:

 int func () asm ("MYFUNC");

 int func ()
 {

g++ will compile it and nm -D output will be

0000000000001e02 T MYFUNC

instead of

0000000000001e02 T _Z4funcv

Tested on g++ 4.9.2

befzz
  • 1,232
  • 13
  • 11
7

You mean so you can export your function from a library? extern "c" { your code here }

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Crashworks
  • 40,496
  • 12
  • 101
  • 170
4

Schaub's answer is factually incorrect. The most common reason to avoid name mangling is because you are building a shared library (on Windows, a DLL) that is used by client software you don't control that expects certain exported function names. Because of mangling differences between compilers, such interfaces have historically avoided name mangling.

What you have to do is this. First, in your source code prepend extern "C" to get rid of C++ mangling; this still leaves C mangling though. Second, use the -Wl,--kill-at command line option when compiling.

Example:

extern"C" __declspec(dllexport) hresult __stdcall MyExportedFunction( ... )
{
     ....
}

And compile with:

gcc -shared -mwindows -Wl,--kill-at -Werror ... -o MyLib.dll MyLib.cpp -lkernel32 -l...

You can verify whether you got it right using Dependency Walker.

Anonymous
  • 41
  • 1
0

If you want to compile to wasm you can add the --demangle option to the wasm-ld linker via clang -Wl,--demangle