名前だけでなくパラメータと戻り値の型でもない関数がCとC++で同じアドレスを共有できないという保証はありますか?私は標準についてそれについては何も見ていない。いくつかの関数のポインタ
#include <cassert>
void foo() {}
void bar() {}
int main()
{
assert(foo != bar);
}
名前だけでなくパラメータと戻り値の型でもない関数がCとC++で同じアドレスを共有できないという保証はありますか?私は標準についてそれについては何も見ていない。いくつかの関数のポインタ
#include <cassert>
void foo() {}
void bar() {}
int main()
{
assert(foo != bar);
}
折りたたみ同一のコードC++ 11標準は
(ポインタ変換後に)同じタイプの
ポインタは比較することができ5.10等価演算子と言い平等のために。同じ型の2つのポインタは、両方がnullの場合、同じ関数を指すポインタ、または両方が同じアドレス(3.9.2)を表す場合に限り、等しいと比較されます。
関数へのポインタがない場合、それらは同じアドレスを持つかもしれませんが、わかりません。 がの場合、2つの異なる関数へのポインタを比較して、等しいとは比較してはいけません。混乱のため
一つの原因は、MSVCコンパイラが(int
とlong
など)さまざまなタイプのため、同一のマシンコードを生成するために起こるテンプレート関数のコードを結合することが知られていることかもしれません。これは準拠していません。
しかし、これは異なるシグネチャの関数であり、正確にはこの質問に関するものではありません。
実装の詳細。
(C99,5.1.2.3p1) "この国際標準の意味論的記述は、最適化問題が無関係な抽象機械の動作を記述している。
引用は空白です。質問は、抽象機械とは異なる実際のコンパイラについてですが、(最適化の存在下であっても)許容される抽象機械の1つと同じ観察可能な動作を示さなければならない。 – MSalters
はい。 C99 6.5.10:6
二つのポインタが比較等しい場合にのみ両方ヌルポインタがある場合、両方 は、オブジェクトへのポインタと サブオブジェクトを含む同じオブジェクトへのポインタ(あるその始まる)または機能、...
編集:段落の残りの部分、それはいくつかの重要性を持っていることが判明するので:
は、どちらも同じ配列 オブジェクトの最後の要素を超えたものへのポインタであり、1つは1つの配列オブジェクト の末尾を指すポインタで、もう1つは異なる配列オブジェクトの先頭へのポインタです アドレス空間の にある最初の配列オブジェクトの直後に起こります。私はそれから取る何
:間違ったオペランドに適用
<
は未定義です。実装は、実際には同じ機能であることを保証してはいけませんか?つまり、コンパイラがこれを最適化するのはいいですが、言語仕様関数はコンパイル後のアセンブリ関数よりも私には違って見えます。 –
Boの答えから、最後の部分は "または両方が同じアドレスを表します"。この見積もりの最後の部分は似ていますか? –
@DanielSloof私はそれが '...'の後に来るものに依存すると思う。 –
最適化がオンになっているコンパイラの多くは、2つの関数が同じアドレスを持つようにします。例えば、msdnから:
/OPT:ICF が同じアドレスをもたらすことができるが、異なる 機能または読み取り専用データメンバ( /GyとでコンパイルCONST変数)に割り当てられます。したがって、/ OPT:ICFは、 関数のアドレスまたは読み取り専用データメンバのアドレスに依存するプログラムを中断することがあります。詳細については、/ Gy( ファンクションレベルリンクを有効にする)を参照してください。
ICFは:
最後のコメントは今や意味をなさない。異なる引数型の場合、異なる関数ポインタがあるため、同じ型の2つの[関数]ポインタに関する規則は適用されなくなります。 – MSalters
それは本当です。異なる関数が同じアドレスを得ることができるが、本当に質問が何を求めているのではないか、 –