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.

时间: 2024-10-13 08:59:24

Name Mangling and extern “C” in C++的相关文章

[C/CPP系列知识] C++中extern “C” name mangling -- Name Mangling and extern “C” in C++

http://www.geeksforgeeks.org/extern-c-in-c/ C++函数重载(function overloading),但是C++编译器是如何区分不同的函数的呢?----是通过在函数名是加些信息来区不同的函数,即所谓的Name Mangling.C++标准并没有对name mangling技术,各个编译器可以添加不同的信息. 考虑下面的函数 int f (void) { return 1; } int f (int) { return 0; } void g (voi

extern "C"

经常看到如下代码: #ifdef _cplusplus extern "C" { #endif #include "XXX.h" #ifdef _cplusplus } #endif 解释: extern "C"的作用是,告诉C++编译器,下面的代码按照C的方式进行编译,说白了,不要对这些函数进行名字重整(function name mangling).通常在C++程序中使用C函数或者模块时,需要用到这个功能. 原因: C++为了支持函数重载,将

【slighttpd】基于lighttpd架构的Server项目实战(11)—C++的Name Mangling

上一节中,我们介绍了插件作为动态库的加载,其中我们注意到 函数: void* dlsym(void* handle,const char* symbol) 返回的是[symbol对应的地址]. 因此,在我们开发的插件中,SetupPlugin和RemovePlugin函数需要添加extern "C" : extern "C" Plugin* SetupPlugin() { return new MyPlugin(); } extern "C" P

C++基础补遗篇—函数重载与Extern C

问题引出 之前提到C存在命名冲突问题,新的C++专门为此引入了namespace机制加以改进(后文介绍),此外还有另一种机制: int add(int i, int j) {    return i+i;  } float add(float a, float b, floatc)  {    return a+b+c;   } void main() { int a = add(8, 9); float b = add(7.7, 8.8, 9.9); } 上例在C环境下不成立,因为C编译器不允

为什么要使用extern "C"

C/C++采用的是分别编译模型, 源代码只要声明函数, 就可调用. 编译时,在函数调用处生成一个符号引用. 链接时,将函数调用处的符号引用,替换成地址(甚至仍有可能继续保留符号, 载入时再计算地址). 所以, 以下两者必须完全比配, 否则链接时会出错. 1. 函数调用处引用的符号名 2. 函数定义处公开的符号名 如何使得两者匹配? 无论是在调用处还是在定义处, 无论是C还是C++(注1), 编译器都会对函数名进行mangling, 产生一个符号名. 而 extern "C" 就是通知C

c++ 名字粉碎(name mangling)

转自Ibm: Name mangling is the encoding of function and variable names into unique names so that linkers can separate common names in the language. Type names may also be mangled. The compiler generates function names with an encoding of the types of th

C/C++:函数的编译方式与调用约定以及extern “C”的使用

函数在C++编译方式与C编译方式下的主要不同在于:由于C++引入了函数重载(overload),因此编译器对同名函数进行了名称重整(name mangle).因此,在C++中引 用其他C函数库时,需要对声明使用的函数做适当的处理,以告知编译器做出适应的名称处理. 函数的调用约定涉及了函数参数的入栈顺序.清栈主体(负责清理栈的主体:函数自身还是调用函数者?).部分名称重整. 如,在C编译方式下有_stdcall._cdecl等调用约定,在C++编译方式下也有_stdcall._cedecl等调用约

DLL编写中extern “C”和__stdcall的作用

动态链接库的使用有两种方式,一种是显式调用.一种是隐式调用. (1)       显式调用:使用LoadLibrary载入动态链接库.使用GetProcAddress获取某函数地址. (2)       隐式调用:可以使用#pragma comment(lib, “XX.lib”)的方式,也可以直接将XX.lib加入到工程中. DLL的编写 编写dll时,有个重要的问题需要解决,那就是函数重命名——Name-Mangling.解决方式有两种,一种是直接在代码里解决采用extent”c”._dec

extern 的使用

extern.h的头文件内 #pragma once extern int a; extern int b; int c;//这里会报错,因为是一个全局变量,被多次包含,相当于重定义. extern.cpp的文件内 #include"extern.h" int a = 3; int b = 4; int c = 5; main.cpp的文件内 #include"extern.h" #include<iostream> using namespace st