3

私は初心者レベルのプログラマーで、C++ でプログラミングを学び始めたばかりです。

「FUNCTION OVERLOADING」と呼ばれる機能を見て、コードレベルでの目的と実装を理解しましたが、コンパイラレベルでの実装方法、つまりコンパイラが署名を区別する方法を理解していませんでした同じ名前の異なる関数と

return-type func-name (data-type 1 , data-type-2);

と同じ署名を持つことになります。

return-type func-name (data-type 2 , data-type-1);

and does the same thing applies to overloaded constructors too ?

4

1 に答える 1

8

コンパイラは、名前マングリングと呼ばれる手法を使用します。

簡単に言えば、コンパイラは引数の数と型を、オブジェクト ファイルに書き込まれる実際の名前にエンコードします。このテーマに関するウィキペディアの記事には、C++ の例を含むいくつかの例があります。

具体的な例として、Mac で g++ を使用して次の C++ ファイルをコンパイルしました。

test.cpp

int f(int x) {}

int f(double x, char y) {}

g++ -S test.cpp

これにより、アセンブリ言語ファイルが生成されます (多少省略されています)。

test.s

.globl __Z1fi
__Z1fi:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    %edi, -4(%rbp)
    leave
    ret
.globl __Z1fdc
__Z1fdc:
    pushq   %rbp
    movq    %rsp, %rbp
    movsd   %xmm0, -8(%rbp)
    movb    %dil, -12(%rbp)
    leave
    ret

ここで重要な点は、関数が呼び出さ__Z1fi__Z1fdc、アセンブリ言語の出力で、リンカが確認できることです。fおそらくそれが関数の名前であると推測できます。引数には、 i(int) とdc(double と char) があります。引数の順序もエンコードされることに注意してください!

もしあなたが持っていたらどうなるか考えてみてください

int f(int x) {}
int f(int y) {}

これはもちろん、言語に関する限り、容認できる状況ではありf(10)ません。理論的には、言語は 2 番目の宣言が最初の宣言を置き換えることを指定できますが、C++ はこれを行いません。これは単に違法なオーバーロードです。

名前マングリングは、これがエラーになる理由を実際に示していることがわかりました。コンパイラは、名前を持つ 2 つの異なる関数を作成しようとします__Z1fi(実際の名前は言語によって定義されていませんが、コンパイラに依存します)。このレベルのプログラムでは、同じ名前の関数を 2 つ持つことはできません。

于 2012-07-07T05:20:36.527 に答える