C++:是否可以区分外部"C"函数和普通函数?

C++: Is it possible to distinguish an extern "C" function from an ordinary function?

本文关键字:函数 外部 是否 C++      更新时间:2023-10-16

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

gcc打印same,在OS X上打印clang

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

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

因此,例如,C 标准指定std::qsort具有两个 Overloads,一个将C链接作为比较函数,并且具有C 链接的函数作为比较功能功能。这只是普通的过载,当您使用任何一个功能类型调用std::qsort时,编译器都应该选择适当的过载。

因此,是的,std::is_same应该是区分两种类型所需的全部。但是,同样,大多数编译器不会将它们视为不同类型。如果您有其中一个编译器(几乎可以肯定的是),那么它们具有相同的类型,并且您无法分辨它们。因此,例如,这些编译器的标准库仅具有一个 std::qsort的版本。