用C++命名Mangling

Nav*_*lam 6 c++ extern

我正在阅读这篇文章 - http://www.geeksforgeeks.org/extern-c-in-c/

给出了两个例子 -

int printf(const char *format,...);

int main()
{
    printf("GeeksforGeeks");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它说这不会编译因为编译器无法找到'printf'函数的错位版本.但是,下面给出输出.

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

int main()
{
    printf("GeeksforGeeks");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是因为extern"C"阻止名称被破坏.但是,代码运行并提供输出.从哪里得到'printf'的定义.我读了一篇帖子,默认包含'stdio.h'.如果是这样,则必须运行以下代码.但是,它给出了未定义printf的错误.

int main()
{
    printf("GeeksforGeeks");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下吗?

ewd*_*ewd 4

您的编译器通过将 printf 特别视为内置函数而很有帮助。

示例代码“tst.cpp”:

int printf(char const *format,...);
int foo(int a, char const *b);

int main() {
    printf("Hello, World!");
    foo(42, static_cast<char const *>("Hello, World!"));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当使用 Microsoft 的 cl 编译器命令“cl /c tst.cpp”进行编译时,我们可以检查生成的 .obj 并发现:

00000000 r $SG2552
00000010 r $SG2554
00000000 N .debug$S
00000000 i .drectve
00000000 r .rdata
00000000 t .text$mn
         U ?foo@@YAHHPBD@Z
         U ?printf@@YAHPBDZZ
00e1520d a @comp.id
80000191 a @feat.00
00000000 T _main  
Run Code Online (Sandbox Code Playgroud)

请注意,foo() 和 printf() 均已损坏。

但是当我们通过 cygwin "g++ -c tst.cpp" 使用 /usr/lib/gcc/i686-pc-cygwin/3.4.4/cc1plus.exe 进行编译时,我们得到:

00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 t .text
         U __Z3fooiPKc
         U ___main
         U __alloca
00000000 T _main
         U _printf
Run Code Online (Sandbox Code Playgroud)

这里 foo() 被破坏了,而 printf() 没有被破坏,因为 cygwin 编译器很有帮助。大多数人会认为这是编译器缺陷。如果使用“g++ -fno-builtin -c tst.cpp”调用 c​​ygwin 编译器,那么问题就会消失,两个符号都会被破坏。

更新的 g++ 是正确的,通过“g++ -c tst.cpp”与 /usr/libexec/gcc/i686-redhat-linux/4.8.3/cc1plus 进行编译,我们得到:

00000000 T main
         U _Z3fooiPKc
         U _Z6printfPKcz
Run Code Online (Sandbox Code Playgroud)

foo() 和 printf() 都被破坏了。

但是如果我们声明 printf 使得 cygwin g++ 无法识别它:

char const * printf(char const *format,...);
int foo(int a, char const *b);

int main() {
    printf("Hello, World!");
    foo(42, static_cast<char const *>("Hello, World!"));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后 foo() 和 printf() 都被破坏了:

00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 t .text
         U __Z3fooiPKc
         U __Z6printfPKcz
         U ___main
         U __alloca
00000000 T _main
Run Code Online (Sandbox Code Playgroud)