name mangling & extern "C"


最初的时候,最老的c++编译器里,c++的代码会被翻译成c的代码,然后再由c的编译器来编译。
那么overloading functions在翻译成c的代码的时候,不能被翻译成同一个名字。
在翻译的过程中,就要结合它的return type,argument给予它新的名字。

这个东西叫做name mangling:

http://app.yinxiang.com/shard/s2/sh/c09d7778-8a92-4726-b01e-3fd8a78026e7/f284c0dee5e454231043d4225663098b
http://app.yinxiang.com/shard/s2/sh/564eaae6-780e-47c9-9a65-1f5e6b48e7ff/4656c781b00d35323b93f7661d001f47


现在来看一段普通的c程序:


// 后缀名为.c 用gcc编译
//declaration of the function in c standard lib
int printf(const char *format,...);

int main()
{
    printf("Hi, loopsaker!!");
    return 0;
}


注意,上面这段程序,就是这个.c文件里面的全部内容了。
我们没有引用任何的headers。
因为,我们只需要声明stdio.h中的一个函数即可,也就是printf
我们如果用c编译器编译的,因为c里面是没有overloading的,也不会有什么overloading,所以printf真的就叫做printf。

在link的时候,能够在c的标准库里面找到这个函数。


如果上面那段程序,后缀名不是c,而是cpp(因为有的编译器会根据后缀名自动转换成c模式),用一个c++编译器来编译,结果会如何呢?
首先,编译器做的第一件事情是做name mangling。
printf会被替换成别的东西。
然后再进行编译。

那么,在link的时候,因为c的标准库里,函数的名字叫做printf ,而你这里mangling之后,已经不叫printf了,于是会出现link error。

那么,如何解决这个问题呢?
任何一个c++编译器,都有一种c模式:


extern "C"{
    int printf(const char *format,...);
}

int main()
{
    printf("Hi, loopsaker!");
    return 0;
}



使用了extern "C",表示,这里面声明的这个函数,不要做任何name mangling


因此,这就是c++的C标准库的headers里面有的东西:

name mangling & extern

你可能感兴趣的:(c++)