25

C ++標準では、等式演算子について次のように述べています==

[C++11: 5.10/1]: [..]同じタイプの2つのポインターは、両方がnullであるか、両方が同じ関数を指しているか、または両方が同じアドレスを表している場合にのみ、等しく比較されます。

私の最初の解釈は、関数はこのレベルでは意味的に「アドレス」自体を持たないため、「または両方が同じアドレスを表す」ことは、関数ではなくオブジェクトを参照することだけを目的としているというものでした。それ以外の場合、なぜ「同じ関数を指す」句を気にするのですか?

つまり、同じタイプの2つの関数ポインタは、両方が同じ関数である期間を指している場合にのみ、等しく比較されます。

この結果、この質問で見られた動作(2つの異なるが同一の関数へのポインターは同じ値を持つ)は実装のバグになります。これは、別個の関数へのポインターが一意である必要があるためです。

これが条項の意図だと思いますが、これが通路の意味を実際に推測する方法であるという見方を客観的に擁護する方法を見つけることができません。解釈が疑問視されています

[D]「[...]または両方が同じアドレスを表す」方法について私と話し合います。VisualC++の動作に満足していません。(@jstine)

ですから、私の質問は、この標準的なパッセージの意図についてです。

また:

  • 私は正しい方向に進んでいます。関数ポインタは、両方が同じ関数を指している場合(「アドレス」は気にしないでください)、または同等に比較する必要があります

  • パッセージには冗長性があります。関数ポインタは、両方が同じ関数を指しているか、両方が同じアドレスを表している場合、等しく比較する必要があります。そして、拡張により、実装は2つの関数を同じアドレスに存在させることができます。

どっち?

4

1 に答える 1

5

さて、論理的にステートメントを見てください。3つの条項があります。

  1. どちらもnullです。

  2. どちらも同じ機能を指しています。

  3. 両方とも同じアドレスを持っています。

これらの句は、論理「または」で結合されます。したがって、これらのいずれかが真である場合、2つのポインターは同等に比較できます。コンパイラがそのように決定した場合、#3に失敗しても、#2に合格する可能性があります。論理「または」は、そのようなポインタが同等に比較されることを意味します。

また、メンバーポインタには、従来の意味での「アドレス」がないことに注意してください。それらには値がありますが、それはメモリアドレスではありません。そのため、それらをキャストすることなどは許可されていませんvoid*

パッセージは、関数ポインタが与えられた場合に、と同じ動作を引き起こすことをt保証します。その動作は、NULLを参照するか、同じ関数を呼び出すか、同じアドレスでコードを実行するかのいずれかになります。したがって、同じ動作が発生します。ut == ut(...);u(...);

技術的には、Mehrdadの問題は、2つの異なるメンバー関数名から同じ値を取得していることです。したがって、#3が適用されます。異なるメンバー関数名がそれらの関数を取得するときに異なる値を返すことを要求する標準には何もありません。

于 2013-01-07T02:29:37.320 に答える