ネーム・マングリングは、
関数名および変数名を固有の名前にエンコードして、
リンカーが言語内の共通名を分離できるようにすることです。また、型名もマングルできます。
モジュールをコンパイルする場合、コンパイラーは関数引き数の型をエンコードして、関数名を生成します。
ネーム・マングリングは、多重定義フィーチャーの機能性および異なるスコープ内での可視性を向上させるために、
一般的に使用されています。
ネーム・マングリングは、変数名にも適用されます。
ネーム・スペース内に変数がある場合、同じ変数名が複数のネーム・スペース内に存在できるように、
ネーム・スペースの名前はこの変数名にマングルされます。
C++ コンパイラーは、C 変数が存在するネーム・スペースを識別するために、C 変数名もマングルします。
マングル名を作成する方法は、ソース・コードをコンパイルするために使用する オブジェクト・モデルによって異なります。特定のオブジェクト・モデルを使用してコンパイルされた クラスのオブジェクトのマングル名は、別のオブジェクト・モデルを使用してコンパイルされた 同じクラスのオブジェクトのマングル名とは異なります。オブジェクト・モデルは、コンパイラー・オプションまたは プラグマによって制御されます。
C++ コンパイラーによってコンパイルされたライブラリーやオブジェクト・ファイルを C モジュール にリンクする場合は、ネーム・マングリングを使用すべきではありません。C++ コンパイラーが 関数名のマングリングを行わないようにするには、次の例のように、宣言またはディレクティブに extern "C" リンケージ指定子を適用します。
extern "C" { int f1(int); int f2(int); int f3(int); };
この宣言によって、関数 f1>、f2、および f3 への 参照をマングルしないようにすることがコンパイラーに通知されます。
extern "C" リンケージ指定子は、C++ 内で定義された関数のマングリングが 行われないようにして、C から呼び出せるようにする場合にも使用できます。 例えば、次のように指定します。
extern "C" { void p(int){ /* not mangled */ } };
複数レベルのネストした extern 宣言では 、宣言内部で extern の指定が一般的に用いられます。
extern "C" { extern "C++" { void func(); } }