Reputation: 6994
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
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