2017-03-12 14 views
4

次のコードについていくらか混乱します。どのようにしてbはまだを参照していますが、異なる値を持っていますか?非constにキャストした後のconst参照の動作

#include <iostream> 
using namespace std; 
int main() 
{ 
    const int a = 5; 
    const int &b = a; 
    ++(int&)b; 
    cout << a << endl;//returns 5 
    cout << b << endl;//returns 6 
    cout << "mem a:" << &a << endl; //returns 0x61ff18 
    cout << "mem b:" << &b << endl; //returns 0x61ff18 
    return 0; 
} 

答えて

11

この動作は定義されていません。

定数ではない定数オブジェクトの定数参照から定数を離してキャストできます。ただし、実数constを参照する参照からの型変換は、未定義の動作につながります。この場合

、コンパイラが変数a自体が一定に最適化されている一方で、先の参照bを作るための場所を提供するために、5を格納するメモリ位置を作成したことが表示されます。ライン

cout << a << endl; 

cout << '5' << endl; 

に最適化されている間、コードは不正ので、まだ5生成、6を製造bによって参照される位置を変更します。

+0

あなたはそれが本当にありませんので、コンパイラは "、5で表現' A'を置き換えるようだ右です結局は未定義です。ありがとう – danwin

+1

@ダンウィンええ、そうです。コンパイラが簡単に説明できる何かを選択したことは無関係です。まだ未定義の動作です。 –

+3

@danwin:この動作はC++ ISO標準では定義されていません。これは、コンパイラが生成した動作について理由を付けることが不可能であるということを意味するものではありません。つまり、C++ルールを確実に使用してその理由を推論することはできません。 –

2

この場合のCスタイルのキャストは、const_castに相当します。 const_castを使用してもともと一定であったもののconstnessをキャストしてから変更しようとすると、の定義されていない動作です。あなたが観察したすべての行動は無作為と見なされ、意味をなす必要はありません。

オブジェクトは、もともと非一定であった場合 安全 const_castを使用することができます

#include <iostream> 

int main() 
{ 
    int a = 5; // <--- non-constant 
    const int &b = a; 
    ++const_cast<int&>(b); 
    std::cout << a << '\n'; // 6 
    std::cout << b << '\n'; // 6 
    std::cout << "mem a:" << &a << '\n'; 
    std::cout << "mem b:" << &b << '\n'; 
} 
+0

_ "const_castを使用してもともと定数だったもののconstをキャストするのは未定義の動作です" _いいえ、そうではありません。 –

+0

@LightnessRacesinOrbit:最初はそれはとにかく明白だと思っていましたが、元々表現されていたように誤解されていたかもしれないと思います。 –

関連する問題