0

タイトルにもありますが、宣言子type-qualifiersの格納場所( など)が影響するのstackか少し戸惑っています。bss

int main()
{
   const int value=5;
   const char *str= "Constant String";
}
  • 上記のコードでは、デフォルトstorage-class-specifierautoです。
  • したがって、これらの定数は、作成時にstack-frameofに割り当てられると想定mainされます。
  • 一般に、pointersスタック内のさまざまなメモリ位置には、そこに含まれる値を自由に変更できます。
  • したがって、上記の点から、格納された要素の性質type-qualifierを保持するためにいくつかのロジックを追加するか(そうであれば、それは何ですか?) 、メモリに格納されることは理解できます。これについて詳しく説明してくださいconstantconstantsread-only-portion

より詳細な例

#include <stdio.h>
int main(void)
{
  int val=5;
  int *ptr=&val;
  const int *cptr=ptr;

  *ptr=10;  //Allowed
  //*cptr=10; Not allowed

  //Both ptr and cptr are pointing to same locations. But why the following error?
  //"assignment of read-only location ‘*cptr’"

  printf("ptr: %08X\n",ptr);
  printf("cptr: %08X\n",cptr);
  printf("Value: %d\n",*ptr);
}

上記の例では、 と の両方が同じ場所cptrptr指しています。しかし、整数cptrへのポインタです。const type qualifiedの値を変更しているcptrときに、コンパイラは「読み取り専用の場所 '*cptr' の割り当て」としてエラーをスローします。しかし、以下の出力のように、同じ場所をで変更できます。説明してくださいptr

ptr: BFF912D8
cptr: BFF912D8
Value: 10
4

2 に答える 2

0

私はあなたの例の詳細には立ち入りませんが、いくつかの一般的な意見を述べたいと思います:

C言語のセマンティクスは、コンパイラーとハードウェアによってある程度まで強制されます。未定義の動作を回避するのはプログラマーの責任です。

適切な例として、セグメンテーション違反(ハードウェアの強制)やコンパイラエラー(キャストがシャットダウンするように指示するため)を取得せずにポインタからconstnessをキャストすることにより、自動ストレージ期間(スタック割り当て)のconst修飾変数を変更することが非常に可能です。あなたはあなたが何をしているのか知っています)。

ただし、言語の制約に違反し、オプティマイザーがもはや成り立たない仮定を行うため、コードは実際には壊れます。

次に、オブジェクトへのアクセスに使用される式のタイプが操作の定義に関連しているという誤解がありますが、そうではありません。

効果的な型付け規則(C996.5§6)は、本質的にCを非常に不健全な型システムを持つ強い型付け言語にします。タイプ情報(可変性の中でも)は、その場所へのアクセス方法に関係なく、オブジェクト(保管場所)自体によって運ばれます。

これにより、constで修飾された保管場所への保管は違法(未定義の動作)になりますが、技術的には可能です(不健全な型システム)。ポインタを介した任意の型のパンニングは、言語のセマンティクスに違反する同じカテゴリの操作に分類されますが、強制されないため、厳密なエイリアシングを想定した場合など、奇妙なバグが発生する可能性があります。

于 2012-10-27T09:27:12.513 に答える
0

あなたの最初の例では:

int main()
{
   const int value=5;
   const char *str= "Constant String";
}

変数valueと文字列リテラルが格納される場所は、実装に任されています。C標準が保証しているのは、これらがテキストセグメント、スタック、または任意の場所にある読み取り専用メモリに格納されることだけです。

あなたの2番目のケースでは:

 int *ptr=&val;
 const int *cptr=ptr;

を変更しようとすると、コンパイラは が指す実際の場所が読み取り専用か書き込み可能*cptrかを気にしません。cptr気にするのはconst、指している場所cptrが読み取り専用であると考えるために使用する型修飾子だけです。

別のバリアント:

    const int i = 5;
    p = &i;
   *p = 99;

この場合、コンパイラーは、ポインターを介して const 値を変更することを許可します。しかし、これは未定義の動作です。

于 2012-10-27T08:51:23.903 に答える