Name Mangling and extern “C” in C++

原文链接:http://www.geeksforgeeks.org/extern-c-in-c/

C++ supports function overloading, i.e., there can be more than one functions with same name and differences in parameters. How does C++ compiler distinguishes between different functions when it generates object code – it changes names by adding information about arguments. This technique of adding additional information to function names is called Name Mangling. C++ standard doesn’t specify any particular technique for name mangling, so different compilers may append different information to function names.

Consider following declarations of function f()

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

 

A C++ compiler may mangle above names to following (Source: Wiki)

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

 


How to handle C symbols when linking from C++?
In C, names may not be mangled as C doesn’t support function overloading. So how to make sure that name of a symbol is not changed when we link a C code in C++. For example, see the following C++ program that uses printf() function of C.

1 // Save file as .cpp and use C++ compiler to compile it
2 int printf(const char *format,...);
3 
4 int main()
5 {
6     printf("GeeksforGeeks");
7     return 0;
8 }

 

Output:

 1 undefined reference to `printf(char const*, ...)'  ld returned 1 exit status 

 

The reason for compiler error is simple, name of printf is changed by C++ compiler and it doesn’t find definition of the function with new name.

The solution of problem is extern “C” in C++. When some code is put in extern “C” block, the C++ compiler ensures that the function names are unmangled – that the compiler emits a binary file with their names unchanged, as a C compiler would do.

If we change the above program to following, the program works fine and prints “GeeksforGeeks” on console.

 1 // Save file as .cpp and use C++ compiler to compile it
 2 extern "C"
 3 {
 4     int printf(const char *format,...);
 5 }
 6 
 7 int main()
 8 {
 9     printf("GeeksforGeeks");
10     return 0;
11 }

 

Output:

 1 GeeksforGeeks 

Therefore, all C style header files (stdio.h, string.h, .. etc) have their declarations in extern “C” block.

1 #ifdef __cplusplus 
2 extern "C" {
3 #endif
4     /* Declarations of this file */
5 #ifdef __cplusplus
6 }
7 #endif

 

Following are main points discussed above
1. Since C++ supports function overloading, additional information has to be added to function names (called name mangling) to avoid conflicts in binary code.
2. Function names may not be changed in C as C doesn’t support function overloading. To avoid linking problems, C++ supports extern “C” block. C++ compiler makes sure that names inside extern “C” block are not changed.

posted @ 2015-09-22 16:18  lyleslie  阅读(185)  评论(0编辑  收藏  举报