5

コードにこれに似たものを書きました

const int x=1;
int *ptr;
ptr = &x;
*ptr = 2;

これはすべてのコンパイラで機能しますか? 定数変数を変更していることに GCC コンパイラが気付かないのはなぜですか?

4

4 に答える 4

9

const実際には「一定」という意味ではありません。Cで「一定」であるものには、コンパイル時に決定される値があります。リテラル42はその一例です。キーワードはconst実際には読み取り専用を意味します。たとえば、次のことを考慮してください。

const int r = rand();

の値はrプログラムの実行時まで決定されませんが、constキーワードは、r初期化後に変更することを許可されていないことを意味します。

あなたのコードでは:

const int x=1;
int *ptr;
ptr = &x;
*ptr = 2;

割り当てptr = &x;制約違反です。つまり、準拠するコンパイラがそれについて文句を言う必要があります。const int*(const intへのポインタ)値を非constint*オブジェクトに合法的に割り当てることはできません。コンパイラが実行可能ファイルを生成する場合(実行する必要はありません。拒否する可能性があります)、動作はC標準で定義されていません。

たとえば、生成されたコードは実際に値2を-に格納する場合がありますが、コンパイラは初期化後に変更できないことを認識しているためx、後で参照するとx値が生成される場合があります。そしてそれはあなたがそう言ったので、として定義することによってそれを知っています。コンパイラに嘘をついた場合、結果は恣意的に悪いものになる可能性があります。1xxconst

実際、起こりうる最悪の事態は、プログラムが期待どおりに動作することです。つまり、検出が非常に難しいバグがあるということです。(しかし、あなたが得るべきだった診断は大きな手がかりになります。)

于 2013-03-22T17:33:34.787 に答える
0

悪いプログラマー。ノームーンパイ!

const を変更する必要がある場合は、const 以外の変数にコピーしてから操作してください。const には理由があります。const を「こっそり」使用しようとすると、実行時に重大な問題が発生する可能性があります。つまり、オプティマイザが値をインラインで使用した可能性があります。

const int x=1;
int non_const_x = x;
non_const_x = 2;
于 2013-03-22T17:04:22.787 に答える
-1

ここでこれについての良い議論があります:邪悪なキャストは邪悪なコンパイラによって打ち負かされますか?

次の理由により、gcc がこれをコンパイルすることを期待します。

  • ptr は x を指すことを許可されています。そうしないと、読み取りが不可能になりますが、以下のコメントが言うように、それは正確には素晴らしいコードではなく、コンパイラは文句を言うべきです。警告オプションは、実際に警告されるかどうかに影響します (私は推測します)。
  • x に書き込むと、コンパイラは const に書き込んでいることを「認識」しなくなります。これはすべて、C のコーダーの手に委ねられています。選択しました。

ただし、それが機能するかどうかは、コードのコンパイル方法、選択したコンパイル オプションに対する const の実装方法、およびターゲット CPU とアーキテクチャによって異なります。それはうまくいくかもしれません。または、クラッシュする可能性があります。または、「ランダムな」メモリビットに書き込み、奇妙な効果を引き起こす(または引き起こさない)可能性があります。それは良いコーディング戦略ではありませんが、それはあなたの質問ではありません:-)

于 2013-03-22T17:06:02.590 に答える