Greg Nisbet
Greg Nisbet

Reputation: 6994

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

Is it possible to distinguish an extern "C" function and a non-[extern "C"] function in C++ at compile time?

They have very different behavior and, evidently, are allowed to have different calling conventions (see https://stackoverflow.com/a/45968482/931154).

The following code snippet suggests that it is not possible to distinguish them using information available at compile time.

#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;
}

prints same with gcc and clang on OS X.

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

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

Upvotes: 1

Views: 118

Answers (1)

Pete Becker
Pete Becker

Reputation: 76315

Functions with C linkage and functions with C++ linkage have different types, even if they take the same argument types and return the same type. (Hmm, sounds familiar). But most compilers don't enforce this rule, and treat them as the same type. (Hmm, sounds familiar).

So, for example, the C++ standard specifies that std::qsort has two overloads, one that takes a function with C linkage as the comparison function, and one that takes a function with C++ linkage as the comparison function. That's just plain overloading, and the compiler is supposed to choose the appropriate overload when you call std::qsort with either function type.

So, yes, std::is_same should be all you need to distinguish the two types. But, again, most compilers don't treat them as different types. If you have one of those compilers (and you almost certainly do), then they have the same type, and you can't tell them apart. Because of that, for example, the standard library for those compilers has only one version of std::qsort.

Upvotes: 1

Related Questions