“ extern“ C””是函数类型的一部分吗? [英] Is `extern "C"` a part of the type of a function?

查看:130
本文介绍了“ extern“ C””是函数类型的一部分吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

除了链接相关的内容外,我在标准中看不到任何注释。

I don't see any comment in the standard except linkage related things.

尽管标准中没有提及调用约定,但是调用约定可能是在现实世界中,C和C ++之间存在差异,因此我希望C函数和C ++函数的类型不同。

Though the standard doesn't say anything about calling convention, the calling conventions might be different between C and C++ in the real world, so I expected that the types of a C function and a C++ function are different. But it seems not, especially in GCC.

#include <type_traits>

extern "C" {
  int c_func(int);
}

int cpp_func(int);

static_assert(!std::is_same<decltype(c_func), decltype(cpp_func)>::value,
              "It should not be the same type");

static_assert 失败,因为GCC认为这些功能具有

static_assert fails since GCC considers those functions have the same type.


  • 外部 C 的一部分函数?

  • 如何检查函数使用C调用约定还是C ++调用约定?

  • Is extern "C" a part of the type of a function?
  • How do I check if a function uses C calling convention or C++ calling convention?

推荐答案

该标准明确表明语言链接确实是函数 type 本身的属性:

The standard makes it clear that language linkage is indeed a property of a function type itself:


所有函数类型,具有外部链接的函数名称以及具有外部链接的变量名称均具有
语言链接。

如果还不够清楚的话,有一个音符(强调我的意思)可以使意图的含义明确:

In case that wasn't clear enough, there's a note (emphasis mine) that makes the intended meaning unambiguous:


[注:因为语言链接是函数类型的一部分,到C
函数,函数所得左值所引用的位置被视为C函数。 — 尾注]

此外,


具有不同语言
链接的两个函数类型是不同的类型,即使它们在其他方面是相同的。

Two function types with different language linkages are distinct types even if they are otherwise identical.

第一个问题的答案是:


  • extern C 是函数类型的一部分。

  • Yes, extern "C" is part of the type of a function.

但是,大多数编译器无法区分具有C和C ++语言链接的函数类型。例如,这是GCC中的一个长期错误( https://gcc.gnu.org/bugzilla/ show_bug.cgi?id = 2316 ;请参见重复列表)。我没有仔细阅读整个线程,但是,如果GCC开始强制执行它们确实是不同类型的规则,那么似乎很多现有代码都会中断。大概这也是为什么其他编译器也未遵循该标准的原因。

However, most compilers fail to distinguish between the types of functions with C and C++ language linkage. This is for example a long-standing bug in GCC (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316; see list of duplicates). I didn't read the entire thread carefully, but it appears that a lot of existing code would break if GCC started enforcing the rule that they really are different types. This is presumably also why other compilers also fail to conform to the standard.

鉴于此,第二个问题的答案似乎是:

Given that, the answer to your second question would seem to be:


  • 在编译时可能没有可移植的方式执行此检查。当然,翻译后,您始终可以进入目标文件,查看名称是否被篡改。

但是<从理论上讲,您的静态断言应该按照您认为的方式工作。

But in theory, your static assertion is supposed to work the way you think it should. That just isn't the case in practice.

附录:

如果我对标准的理解是正确的,那么例如下面的函数模板

If my understanding of the standard is correct, then for example the following function template

template <typename R, typename... A>
void f(R(*)(A...));

无法实例化以生成将接受带有C语言链接的函数的指针的函数参数,因为类型 R(*)(A ...)是指向具有C ++语言链接的功能的指针,接受类型为<$的参数c $ c> A ... 并返回 R

cannot be instantiated to produce a function that would accept a pointer to a function with C language linkage as an argument, since the type R(*)(A...) is "pointer to function with C++ language linkage taking arguments of types A... and returning R".

如果是编译器确实是这样工作的,很容易看出如何确定一个函数是否具有C或C ++语言链接。

If compilers really worked like this, it's easy to see how you could generically determine whether a function has C or C++ language linkage.

但是此示例还应明确说明存在的程度很差如果编译器确实以这种方式工作,则代码将中断。

But this example should also make it clear how badly existing code would break if compilers really worked this way.

这篇关于“ extern“ C””是函数类型的一部分吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆