0

すべての場合に const で修飾された識別子は読み取り専用として保存されますか? それとも実行時に決定されますか?そして、「読み取り専用」メモリに書き込もうとすると、正確には何が起こるか、および/または何が起こる可能性がありますか。

const char **cpp;
char *p;
const char c = 'A';
cpp = &p;
*cpp = &c;
*p = 0;

いずれにせよ、このコードは RO メモリを変更しますか? それとも、実行するたびにRO memではなかったので、これは機能しましたか? その場合、char が RO mem に格納されていて、このコードを実行するとどうなりますか? 動作は未定義であり、問​​題ではありません。しかし、このコードは実行可能です。私の質問は次のとおりです。読み取り専用メモリを変更するとどうなりますか?

4

3 に答える 3

2

基本的に、コンパイラに依存します。ほとんどの場合、char はスタックに置かれ、読み取り専用にはなりません (constつまり、型変換を混乱させるだけで、実行可能ファイルには何も含まれません)。スタックが読み取り専用になることはありません。

const一部をグローバルとして定義すると、DATA読み取り専用ではないセグメントに入る可能性が高くなります。したがって、再びすべてが機能するようになります。コンパイラがすべての const を読み取り専用アクセスの特別なセグメントに入れることは想像できますが、その場合、通常のアクセス違反/セグメンテーション違反が発生します。

また、コード全体を最適化し、出現する const 変数名をその値で置き換える賢いコンパイラを使用している可能性があります。その場合、この変数の変更については何もわかりません。おそらく、コンパイラは&c、変数をどこかに格納する必要があることを理解するのに十分なほど賢いでしょう。

複数の最も可能性が高いことに注意してください。未定義の動作は未定義の動作であるため、何が起こるかわからないため、この回答を読む必要があります。

于 2013-08-16T08:57:12.573 に答える
2

これは未定義の動作です。つまり、何が起こるかを確実に知ることはできません。

また、const変数は読み取り専用メモリにある必要はありません。

C11 6.7.3 型修飾子

const 修飾されていない型の左辺値を使用して、const 修飾された型で定義されたオブジェクトを変更しようとした場合、動作は未定義です。volatile 修飾されていない型の左辺値を使用して、volatile 修飾された型で定義されたオブジェクトを参照しようとした場合、動作は未定義です。

于 2013-08-16T08:49:56.280 に答える
1

まず、const実装での読み取り専用メモリ テクノロジの使用については何も保証しません。変数が不変であることをコンパイラに伝えるだけです。コンパイラは、この不変条件をいつ破るかを通知できます。コンパイラは、最適化などの他の賢いことを行ったり、特別なストレージ技術を利用したりすることがありますが、それはすべて実装固有の詳細です。

于 2013-08-16T08:57:21.823 に答える