2

以下のコード スニペットを検討してください。

int main()
{
    const int i=3;
    int *ptr;

    ptr=const_cast<int*>(&i);
    *ptr=5;

    cout<<"i= "<<i<<endl;  <------------------- statement 1
    cout<<"*ptr= "<<*ptr<<endl;  <------------- statement 2

    return 0;
}

私は次のように出力を得ています:

i= 3
*ptr= 5

http://ideone.com/Bvme6

iポインターを介して値が変更されないのはなぜですか?

const として明示的に宣言されている変数の const-ness をキャストし、その値を変更することは「未定義の動作」であることを知っています。知りたいのですが、「コンパイラーがプログラム内の変数を値に置き換える」のは、コンパイラーの最適化メカニズムですか? これは、ステートメント 1 がコンパイラによって次のように解釈されることを意味します。

cout<<"i= "<<3<<endl;

発言があっても

ptr=const_cast<int*>(&i);    

に置き換えられます

 ptr=(int*)(&i);

同じ出力が得られます: http://ideone.com/5lzJA

4

5 に答える 5

2

コンパイラがプログラム内の変数を値に置き換えるのは、コンパイラ最適化メカニズムですか?

はい; そのため、値が変化することはありません。オブジェクトを変更しようとする動作は、constそのような最適化を可能にするために(また、オブジェクトを書き込み不可能なメモリに配置できるようにするために)未定義のままになります。

于 2012-07-27T15:19:58.713 に答える
1

最適化ではありません。最適化とは、プログラムを、同じ動作をするが使用するリソースが少ない別のプログラムに変換することです。プログラムには定義された動作がないため、同じ動作をもたらす変換をプログラムに適用することはできません。

于 2012-07-27T15:35:46.770 に答える
0

これはconstintである可能性が高いため、コンパイラーは最適化を行い、iの値に直接置き換えています。

于 2012-07-27T15:19:42.383 に答える
0

私は同じ問題を抱えていました.volatileを追加しました.今は変更中です:

#include<iostream>
using namespace std;

int main()
{
  volatile const int a=5;
  int *p = const_cast<int*>(&a);
  *p=6;
  cout<<"a="<<a;
  return 0;
}

出力:

a=6

volatile は、識別子を変更できることをコンパイラに伝えます (このコードで変更できない場合は、別のコードで変更するため、最適化を実行しないでください)。

于 2014-03-04T12:14:24.217 に答える
0

i ptrが指すメモリの保護領域に格納できます。もちろん、何でもあり得るので、それが未定義である理由です。これは基本的に、未定義の動作をトリガーしようとした場合に発生する特定の動作に依存しないことを意味します。

コンピューターが心停止に陥ったり、レーザービームを発射し始めたりする可能性があることはわかっていますが、それが... (_ _ _ _ を待つ) ...未定義;) であるため、決してわかりません;)。

于 2012-07-27T15:25:42.987 に答える