Cプログラミング
 Computer >> コンピューター >  >> プログラミング >> Cプログラミング

C++でManglingとextern「C」に名前を付けます


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

注: これらのコードブロックは、コンパイラごとに異なる結果を生成する可能性があります。


  1. C ++とC#の違い

    C ++は、静的に型付けされ、コンパイルされた、汎用の、大文字と小文字を区別する、自由形式のプログラミング言語であり、手続き型、オブジェクト指向、およびジェネリックプログラミングをサポートします。 C ++は、高水準言語と低水準言語の両方の機能の組み合わせで構成されているため、中水準言語と見なされます。 C#は、アンダース・ヘルスバーグが主導する.NETイニシアチブ内でMicrosoftが開発した、シンプルでモダンな汎用のオブジェクト指向プログラミング言語です。 以下は、C ++とC#の違いです。 メモリ管理 C ++には手動のメモリ管理がありますが、メモリ管理はC#で自動的に処理され

  2. C ++およびC#でのForeach

    C++でのForeach C ++ 11では、各要素をトラバースするforeachループが導入されました。これが例です- 例 #include <iostream> using namespace std; int main() {    int myArr[] = { 99, 15, 67 };    // foreach loop    for (int ele : myArr)    cout << ele << endl; } 出力 99 15 67 Foreac