C ++:是否可以区分extern" C"普通函数的函数?

时间:2017-08-31 02:53:02

标签: c++

是否可以在编译时区分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 gccclang

% g++ --std=c++11 externcsame.cpp && ./a.out
same

% clang++ --std=c++11 externcsame.cpp && ./a.out
same

1 个答案:

答案 0 :(得分:1)

具有C链接的函数和具有C ++链接的函数具有不同的类型,即使它们采用相同的参数类型并返回相同的类型。 (嗯,听起来很熟悉)。但是大多数编译器都没有强制执行此规则,并将它们视为同一类型。 (嗯,听起来很熟悉)。

因此,例如,C ++标准指定std::qsort具有两个重载,一个将带有C链接的函数作为比较函数,另一个带有C ++函数的重载连接作为比较功能。这只是简单的重载,当您使用任一函数类型调用std::qsort时,编译器应该选择适当的重载。

所以,是的,std::is_same应该是区分这两种类型所需的全部内容。但是,大多数编译器都不会将它们视为不同的类型。如果你有一个这样的编译器(你几乎肯定会这样做),那么它们具有相同的类型,你不能区分它们。因此,例如,这些编译器的标准库只有一个版本的std::qsort