2016-10-07 7 views
0

以下の2つのケースを考慮してください。 ケース1:コンパイラエラー - >エラー:読み取り専用Constant intcecement

#include<stdio.h> 
    main() 
    { 
    const int x=5; 
    printf("%d",++x); 
    } 

「X」変数をケース2の増分は:出力6.なぜで正常に実行されましたか?

#include<stdio.h> 
    main() 
    { 
    const int x=5; 
    int *ptr=&x; 
    ++(*ptr); 
    printf("%d",x); 
    } 
+3

2つ目は*未定義の動作*につながります。定数 'int'を変更するには、定数でない' int'へのポインタを使います。良いコンパイラは警告を出し、そうでなければより多くの警告を発するべきです。 –

+1

警告:初期化はポインタのターゲット型からの修飾子を破棄します –

+0

したがって、case2はint型* ptr =&xでなければなりません。 –

答えて

3

int *ptr=&x;制約違反、すなわち、 "エラー"、無効なコードです。 C言語ではconst int *型からint *型への暗黙的な変換はサポートされていません。あなたのコンパイラは確かにこのための診断メッセージを発行しました。

この診断メッセージの後、コンパイラが何らかの形でコンパイルすることに同意したと仮定して、プログラムの動作はC言語では定義されなくなりました。多くのCコンパイラは、たとえデフォルトモードでそれを受け入れるとしても、このコードのコンパイルを拒否するように設定することができます。

あなたは、これは上記の制約違反を取り除くでしょうキャスト

int *ptr = (int *) &x; 

を使用して変換を強制することができます。コンパイラはあなたのコードを受け入れる必要があります(いくつかの注意点があります)。しかし、その変更の後、++*ptrを実行しようとすると、constオブジェクトを変更しようとするため、未定義の動作がトリガーされます。

+0

したがってcase2はint1 * ptr =&xでcase1の場合と同じ動作をする必要があります。 –

+0

@Vijay S B:はい、それを行う方法の1つです。明示的な変換(上記を参照)を強制的に解除して、エラーを取り除くこともできますが、代わりにUBを実行します。 – AnT

関連する問題