How to Compile a C++ Code in Gcc (G++) to See The Name Mangling on Overloaded Functions

How to compile a C++ code in gcc (g++) to see the name mangling on overloaded functions?

For GCC try using:

-Xlinker -Map=output.map

http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html

This will generate a map file which will have all of the mangled symbol names.

And for MSVC:

http://msdn.microsoft.com/en-us/library/k7xkk3e2(v=vs.80).aspx

This will generate something such as:

0002:00094190       ??0SerializationException@EM@@QAE@ABV01@@Z 10148190 f i y:foo.obj

Assuming I don't use ANY overloaded functions, is there a way I can stop ALL name mangling?

As you have mentioned to disable name mangling using the extern "C" { } syntax to surround the function declarations you don't wan't to have mangled names for

extern "C" {
int foo(int x, int y);
void bar(const char* cstr);
}

The easier way, if you are sure you're not using any c++ specific features, is to use the c-compiler to compile your code. For e.g. GCC toolchain call gcc instead of g++.

UPDATE:
The advantage of the extern method is that you can still use c++ features for the implementation (in a separate .cpp compilation unit), which is of course not possible when compiling your code as pure c-code. E.g.

#include "MyExportAPI.h"
#include <string>

void bar(const char* cstr) {
std::string s(cstr); // <<< Note!
}

Why can't C functions be name-mangled?

It was sort of answered above, but I'll try to put things into context.

First, C came first. As such, what C does is, sort of, the "default". It does not mangle names because it just doesn't. A function name is a function name. A global is a global, and so on.

Then C++ came along. C++ wanted to be able to use the same linker as C, and to be able to link with code written in C. But C++ could not leave the C "mangling" (or, lack there of) as is. Check out the following example:

int function(int a);
int function();

In C++, these are distinct functions, with distinct bodies. If none of them are mangled, both will be called "function" (or "_function"), and the linker will complain about the redefinition of a symbol. C++ solution was to mangle the argument types into the function name. So, one is called _function_int and the other is called _function_void (not actual mangling scheme) and the collision is avoided.

Now we're left with a problem. If int function(int a) was defined in a C module, and we're merely taking its header (i.e. declaration) in C++ code and using it, the compiler will generate an instruction to the linker to import _function_int. When the function was defined, in the C module, it was not called that. It was called _function. This will cause a linker error.

To avoid that error, during the declaration of the function, we tell the compiler it is a function designed to be linked with, or compiled by, a C compiler:

extern "C" int function(int a);

The C++ compiler now knows to import _function rather than _function_int, and all is well.

View Compiler Mangled Names in C++

You could look in the map file. Assuming you have map file generation turned on.

How can i avoid name mangling?

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.

Java call to C library compiled by GCC works, but fails when it was compiled with G++

C and C++ are different languages and follows different compilation rules. If you compile with g++, then the code will be treated as C++ not C. It's common pitfall of misconception that C++ is superset of C.

C++ does something called name mangling: encoding function and variable names into unique names so that linkers can separate common names in the language. Thanks to it, features like function overloading are possible.

Let's consider an example (source):

int  f (void) { return 1; }
int f (int) { return 0; }
void g (void) { int i = f(), j = f(0); }

The above may be changed by compiler to:

int  __f_v () { return 1; }
int __f_i (int) { return 0; }
void __g_v () { int i = __f_v(), j = __f_i(0); }

Even though the name of g() is unique, is still mangled. Name mangling applies to all C++ symbols.

If you want to prevent name mangling you need to use extern "C"{} block (but the above example will result in error as C doesn't have function overloading).

Assuming I don't use ANY overloaded functions, is there a way I can stop ALL name mangling?

As you have mentioned to disable name mangling using the extern "C" { } syntax to surround the function declarations you don't wan't to have mangled names for

extern "C" {
int foo(int x, int y);
void bar(const char* cstr);
}

The easier way, if you are sure you're not using any c++ specific features, is to use the c-compiler to compile your code. For e.g. GCC toolchain call gcc instead of g++.

UPDATE:
The advantage of the extern method is that you can still use c++ features for the implementation (in a separate .cpp compilation unit), which is of course not possible when compiling your code as pure c-code. E.g.

#include "MyExportAPI.h"
#include <string>

void bar(const char* cstr) {
std::string s(cstr); // <<< Note!
}

C++ name mangling decoder for g++?

You can use c++filt to demangle c++ symbols. For instance

$ c++filt -n _Z1fv
f()


Related Topics



Leave a reply



Submit