2016-05-06 12 views
0

私はこれをやってfollowing-デ・参照するポインタ

 const int temp=10; 
     int *ptr= &temp; 
     *ptr=100; 

を行うと、私はCONST int型へのポインタを参照解除することができるしています。 constデータ変数は読み込み専用の.rodataに格納されます。

このセクションにはどのように書き込むことができますか?なぜそれは失敗しないのですか?

PS。私はコンパイル時の警告を得るだけです:初期化はターゲットタイプへのポインターから 'const'修飾子を破棄します

+0

'int * ptr = &temp;'は制約違反です。コンパイラが文句を言っていない場合、コンパイラを正しく呼び出す方法を見つけ出す –

+0

これは、メモリを扱う際にC/C++で得られる柔軟性のためです。あなたが何をしているのかが分かっていれば、この柔軟性は他の人にはセグメンテーション違反が予想されます。しかし、コンパイラは、そのような柔軟性を警告/警告する良い仕事をしています。 – sameerkn

答えて

3

.rodataであることは確信していますか?このコード

const int temp = 10; 
int main(void) { 
    int *ptr = &temp; 
    *ptr = 100; 
} 

LinuxではGCC 5.2.1がクラッシュします。 nmは、temp.rodataに存在することを示します。しかし

、変数は自動記憶域期間を持っており、それが.rodataセクションの読み取り専用ページに存在する代わりに、そのスタック上に配置されているので

int main() { 
    const int temp = 10; 
    int *ptr = &temp; 
    *ptr = 100; 
} 

が、クラッシュしません。


またC11ドラフトn1570、6.7.3項6:

試みは非constと左辺値を使用してconst -qualifiedタイプで定義されたオブジェクトを変更するためになされた場合 - 修飾タイプの場合、の動作は未定義です。 [...]

そしてもちろん、未定義の動作は次のことを意味します

行動を、移植性や誤ったプログラム構築物の使用時や、この国際規格は何の要件を課していないそのため、誤ったデータの

実際に何かが起こる可能性があり、プログラムがこれでクラッシュしなくても、それは間違いです。いずれの場合においても


、あなたは警告を得ました。 Cコンパイラが警告を発するときはいつでも、実際にはプログラマとしてエラーを受け取ります(具体的には-Werrorを設定しても)。実際にはエラーであるこれらのことを真のエラーにすることはできないという、ある種の悪い振る舞いに依存する古いコードがたくさんあるだけです。それは完璧であるような有効なC、とだけあなたは未定義の動作が発生し、このptr経由tempを変更しようとするたびに - C標準はint *ptr = &temp;が間違っていることを言っていないことを

注意。

関連する問題