gpt4 book ai didi

c++ - 使用 extern "C"时类型与先前的外部声明不匹配

转载 作者:太空宇宙 更新时间:2023-11-04 10:04:21 26 4
gpt4 key购买 nike

我一直在读一本关于编译器和链接器的书。这本书给出了一个关于使用 extern "C"来测试名称修改的演示:

#include <stdio.h>

namespace myname{
int var = 42;
}

extern "C" double _ZN6myname3varE;

int main(){
printf("%d\n", _ZN6myname3varE);
return 0;
}

书上说它会打印 42 但我在编译时遇到错误。I『使用:

g++ test_extern_c.cpp -o test_extern_c

并得到:

test_extern_c.cpp:15:19: error: type mismatch with previous external decl of ‘double _ZN6myname3varE’ [-fpermissive]
extern "C" double _ZN6myname3varE;
^
test_extern_c.cpp:12:9: note: previous external decl of ‘int myname::var’
int var = 42;
^
test_extern_c.cpp:15:19: error: redeclaration of ‘double _ZN6myname3varE’
extern "C" double _ZN6myname3varE;
^
test_extern_c.cpp:12:9: note: previous declaration ‘int myname::var’
int var = 42;

所以我想知道会发生什么。我还将 _ZN6myname3varE 的类型更改为 int。这会给编译器错误:

test_extern_c.cpp:15:16: error: redeclaration of ‘int _ZN6myname3varE’
extern "C" int _ZN6myname3varE;
^
test_extern_c.cpp:12:9: note: previous declaration ‘int myname::var’
int var = 42;

我的环境和书中的环境有什么不同吗?或者可能是不同版本的g++有不同的规则?

我做了一些浏览器:

  1. 删除代码extern "C"double _ZN6myname3varE;可以编译,结果是42。
  2. 将代码 extern "C"double _ZN6myname3varE; 移动到命名空间的顶部并更改类型:

    #include <stdio.h>

    extern "C" int _ZN6myname3varE;

    namespace myname{
    int var = 42;
    }

    //extern double _ZN6myname3varE;

    int main(){
    printf("%d\n", _ZN6myname3varE);
    return 0;
    }

结果也是42。

最佳答案

请记住,name mangling 是特定于实现的功能,并且未由 C++ 标准定义。因此,并非所有 C++ 编译器都会为相同的声明生成相同的错位名称。

但是,GNU 编译器使用 IA64 ABI名称修饰规范。从这个意义上说,您的示例 _ZN6myname3varEmyname::var 的变形表示,但类型由声明确定,即 int 用于 myname::var 的前声明。并且编译器将后者视为同名的重新声明,这是被禁止的。

关于c++ - 使用 extern "C"时类型与先前的外部声明不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53680778/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com