是否可以在编译时区分C ++中的extern "C"
函数和非[extern "C"
]函数?
他们有非常不同的行为,显然,他们可以有不同的调用约定(参见https://stackoverflow.com/a/45968482/931154)。
以下代码段表明无法使用编译时可用的信息区分它们。
#include <iostream>
#include <type_traits>
int cpp_add(int x, int y) { return x + y; }
extern "C" int c_add(int x, int y) { return x + y; }
typedef decltype(cpp_add) cpp_t;
typedef decltype(c_add) c_t;
constexpr bool sameness = std::is_same<cpp_t, c_t>::value;
int main(int argc, char *argv[]) {
if (sameness)
std::cout << "same" << std::endl;
else
std::cout << "different" << std::endl;
return 0;
}
在OS X上打印same
gcc
和clang
。
% g++ --std=c++11 externcsame.cpp && ./a.out
same
% clang++ --std=c++11 externcsame.cpp && ./a.out
same
答案 0 :(得分:1)
具有C链接的函数和具有C ++链接的函数具有不同的类型,即使它们采用相同的参数类型并返回相同的类型。 (嗯,听起来很熟悉)。但是大多数编译器都没有强制执行此规则,并将它们视为同一类型。 (嗯,听起来很熟悉)。
因此,例如,C ++标准指定std::qsort
具有两个重载,一个将带有C链接的函数作为比较函数,另一个带有C ++函数的重载连接作为比较功能。这只是简单的重载,当您使用任一函数类型调用std::qsort
时,编译器应该选择适当的重载。
所以,是的,std::is_same
应该是区分这两种类型所需的全部内容。但是,大多数编译器都不会将它们视为不同的类型。如果你有一个这样的编译器(你几乎肯定会这样做),那么它们具有相同的类型,你不能区分它们。因此,例如,这些编译器的标准库只有一个版本的std::qsort
。