提问人:MattTT 提问时间:6/9/2023 最后编辑:MattTT 更新时间:6/9/2023 访问量:81
extern “C”:为什么 Visual C++ 在变量和函数的冲突链接规范上表现不同?
extern "C": Why does Visual C++ behave different on conflicting linkage specs for variables vs. for functions?
问:
如果变量在没有其他地方声明(例如在头文件中),然后用 定义,则 Visual C++ 编译器会使用 C++ 链接对其进行编译,恕不另行通知:extern "C"
extern "C"
extern IntStruct ifcStruct;
extern int ifcVar;
/* ... */
extern "C"
{
IntStruct ifcStruct;
int ifcVar = 0;
}
dumpbin /symbols test.obj
显示带有错误名称的 C++ 符号:
00C 00000000 SECT4 notype External | ?ifcStruct@@3UIntStruct@@A (struct IntStruct ifcStruct)
00D 00000008 SECT4 notype External | ?ifcVar@@3HA (int ifcVar)
但是,当一个函数被声明为 without 然后用extern "C"
extern void ifcf ();
/* ... */
extern "C" void ifcf () {}
然后,Visual C++ 编译器会给出不同的错误消息:
test.cpp(20): error C2732: linkage specification contradicts earlier specification for 'ifcf'
test.cpp(20): note: see declaration of 'ifcf'
对于标准引起的这种差异,是否有解释?
无论是否使用 .
函数声明是用还是没有 .
变量声明需要 - 否则就是“重新定义”。但是,无论是在声明中还是在定义中指定,还是在两者中指定,都没有区别。在所有情况下,第一次出现定义语言链接。extern "C"
{...}
extern
extern
编辑:正如 Karen 所说,函数上的行为由 Microsoft
和 cppreference.com 描述:
可以在没有链接规范的情况下重新声明函数 声明时带有语言规范,即第二个声明 将重用第一语言链接。反之则不然:如果 第一个声明没有语言链接,假设为“C++”, 使用另一种语言重新声明是错误的。
答:
从这里开始
如果一个函数具有多个链接规范,则必须达成一致。将函数声明为同时具有 C 和 C++ 链接是错误的。此外,如果程序中出现两个函数声明,一个具有链接规范,另一个没有链接规范,则具有链接规范的声明必须排在最前面。任何已具有链接规范的函数的冗余声明都将被赋予第一个声明中指定的链接。
正如你所看到的,根据引文,带有说明符的函数声明应该首先出现。extern "C"
extern "C" void ifcf ();
/* ... */
extern void ifcf () {} // OK
////////////////////////////
extern void ifcf ();
/* ... */
extern "C" void ifcf () {} // extern "C" is after the first declaration. NOT OK
但是,情况有所不同extern "C" {...}
第一个告诉编译器,如果块内有具有外部链接的名称或符号,请使用 C 命名,否则使用 C++ 名称修改。但是,只要您在内部定义了名称,它们就具有内部链接,因此不使用 C 命名。从 9.11.5 可以看出extern "C" {...}
联动规格嵌套。当联动规格嵌套时,最里面的那个决定了语言 联动。链接规范不建立范围。链接规范应仅在以下情况下出现 命名空间范围 (6.4)。在链接规范中,指定的语言链接适用于函数类型 所有函数声明符、具有外部链接的函数名称和具有外部链接的变量名称 在链接规范中声明
评论
External
extern "C" {...}
评论
extern "C"
对于变量来说没有任何意义。使用变量可以解决什么问题?你认为你为什么需要它?extern "C"