具有 ‘C’ 连接的函数的声明冲突。

huangapple go评论64阅读模式
英文:

Conflicting declaration of function with ‘C’ linkage

问题

以下是您要的翻译部分:

以下代码可以编译而没有错误:

extern "C" void func( void );
extern void func( void );

如果我改变声明的顺序,

extern void func( void );
extern "C" void func( void );

我会得到编译器错误:conflicting declaration of ‘void func()’ with ‘C’ linkage
C++标准规定:

  • 具有特定名称的函数只能有一个具有 "C" 连接(不考虑命名空间)。

在这两种情况下,它是同一个函数。我的假设是C++编译器在内部存储它将编译的函数签名。在第一个示例中,编译器认为第二个声明是有效的,并使用第一个声明进行编译。在第二个示例中,情况并非如此。它将这两个声明视为不同的声明。
有关其背后的技术细节是什么?
gcc 9.4.0 和 msvc 19.29.30147。

英文:

Following compiles without error:

extern "C" void func( void );
extern void func( void );

If I change order of declarations,

extern void func( void );
extern "C" void func( void );

I get compiler error: conflicting declaration of ‘void func()’ with ‘C’ linkage.
C++ standard says:

  • At most one function with a particular name can have "C" linkage (regardless of namespace)

In both cases it is the same function. My assumption is that C++ compiler stores internally functions signature it will compile. In first example, compiler consideres second declaration as valid and uses first declaration to compile. In second example it is not the case. It regrads both declarations as diferent declaration.
What are technical details behind it?
gcc 9.4.0 and msvc 19.29.30147

答案1

得分: 5

函数的重新声明不需要重复它们的链接规范。根据 语言链接 来自 cppreference:

在用语言规范声明函数之后,可以无需再次声明具有语言链接规范的函数,第二个声明将重用第一个语言链接。相反则不成立:如果第一个声明没有语言链接,它被假定为 "C++",再次用另一种语言重新声明将会产生错误。

在第一个片段中,您使用 "C" 链接声明一个函数,然后稍后再次声明时未指定链接。这是可以的;会假定原始链接。然而,在第二个片段中,您使用(隐式的)"C++" 链接声明函数,然后稍后尝试使用 "C" 链接重新声明——这将产生冲突,因此会出现错误。

英文:

Re-declarations of a function are not required to repeat their linkage specification. Per Language linkage from cppreference:

> A function can be re-declared without a linkage specification after it was declared with a language specification, the second declaration will reuse the first language linkage. The opposite is not true: if the first declaration has no language linkage, it is assumed "C++", and redeclare with another language is an error.

In the first snippet, you declare a function with "C" linkage and then later re-declare it with no explicit linkage. This is okay; the original linkage is assumed. However, in the second snippet, you declare a function with (implicit) "C++" linkage, and then later attempt to re-declare it with "C" linkage---that's a conflict, hence the error.

huangapple
  • 本文由 发表于 2023年2月14日 00:15:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75438483.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定