コンパイル時にextern "C"
関数と非[extern "C"
]関数をC++で区別することはできますか?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上のプリントgcc
とclang
とsame
C++リンケージを持つC結合および機能を持つ
% g++ --std=c++11 externcsame.cpp && ./a.out
same
% clang++ --std=c++11 externcsame.cpp && ./a.out
same
あなたのシステムに同じ呼び出し規約がありますか? –
@VladimirBerezkin私はそれがシステムに依存するとは思わない。私はテンプレートが展開されるときに起こる動作について尋ねています...システム依存のものが実際に結果に影響を与えるチャンスを持つ前のものです。 –
より正確には、ポインターを呼び出すときに使用されるもの以外の呼び出し規約のポインターを、そのようなポインターを取得するためにキャストせずに持つことができるかどうかです。いいえ。実際には、呼び出し規約はデフォルトではすべての既存のコンパイラと同じであるため、問題はかなり疑問です。 –