C では、関数のオーバーロード機能を使用できます。この機能を使用すると、同じ名前の関数を作成できます。唯一の違いは、パラメータのタイプとパラメータの数です。ここでは戻り値の型は考慮しません。ここで問題は、C がオブジェクト コード内のオーバーロードされた関数をどのように区別するかということです。
ターゲット コードでは、パラメーターに関する情報を追加して名前を変更します。ここで適用される手法は名前マングリングと呼ばれます。 C 標準化された名前マングリング手法はありません。したがって、コンパイラが異なれば、使用する技術も異なります。
次に、名前マングリングの例を示します。オーバーロードされた関数の名前は func() で、別の関数 my_function() があります。
int func(int x) { return x*x; } double func(double x) { return x*x; } void my_function(void) { int x = func(2); //integer double y = func(2.58); //double }
一部の C コンパイラは以下のように変更します -
int __func_i(int x) { return x*x; } double __func_d(double x) { return x*x; } void __my_function_v(void) { int x = __func_i(2); //integer double y = __func_d(2.58); //double }
C は関数のオーバーロードをサポートしていないため、C をリンクするときC のコードでは、シンボルの名前が変更されないことを確認する必要があります。次の C コードはエラーを生成します。
int printf(const char *format,...); main() { printf("Hello World"); }
undefined reference to `printf(char const*, ...)' ld returned 1 exit status
この問題は、コンパイラが printf() の名前を変更するために発生します。そして、 printf() 関数の更新された定義が見つかりません。この問題を解決するには、C で extern "C" を使用する必要があります。 C コンパイラは、このブロック内で一部のコードが使用されるときに関数名が破壊されないようにします。なので名前は変わりません。したがって、この問題を解決するには、上記のコードは次のようになります。
extern "C" { int printf(const char *format,...); } main() { printf("Hello World"); }
Hello World
注:これらのコード ブロックは、コンパイラごとに異なる結果を生成する可能性があります。
以上がC++ における名前の混乱と extern 'C'の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。