1

IRCについて誰かと話し合ったところ、この質問が出てきました。標準では、型のオブジェクトを左辺値で変更することが許可されていintますchar

int a;
char *b = (char*) &a;
*b = 0;

位置合わせが正常であることがわかっている場合、これを反対方向に実行することは許可されますか?

私が見ている問題は、エイリアシングルールを非対称関係と見なす場合、エイリアシングルールが次の単純なケースをカバーしていないことです。

int a;
a = 0;

その理由は、各オブジェクトに一連のsizeof(obj) unsigned charオブジェクト(「オブジェクト表現」と呼ばれる)が含まれているためです。を変更するintと、それらのオブジェクトの一部またはすべてが変更されます。ただし、エイリアシングルールではintcharまたはを変更することは許可されているだけで、その逆は許可されてunsigned charいません。もう一つの例

int a[1];
int *ra = a;
*ra = 0;

3.10 / 15(「...を含む集合体または共用体型」)では一方向のみが記述されますが、今回は逆の方向(「要素または非静的データメンバー型である型)が必要です。集計...")。

他の方向が暗示されていますか?この質問はCにも当てはまります。

4

3 に答える 3

2

エイリアシング規則は、メモリ内の特定のオブジェクトに対して 1 つの「有効な型」(C99 6.5.7 と脚注 73 を追加) が存在し、そのようなオブジェクトへのアクセスは次のいずれかを通過することを単純に述べています。

  • 有効な型と互換性のある型 (constおよびなどの修飾子、およびrestrict符号付き/符号なしの性質は異なる場合があります)
  • そのような型の 1 つを含む構造体または共用体
  • 文字タイプ

もちろん、有効な型は高度に指定されていません-それはエイリアシングを指定するために使用される単なる構造です。ただし、その意図は、文字以外の2 つの異なる型を持つ同じオブジェクトにアクセスしないことです。

答えは、はい、実際に別の方向に進むことができるということです。

于 2011-01-21T13:28:57.023 に答える
1

標準 (C99 6.3.2.3 §7) では、このようなポインター キャストを「問題なく」定義しており、キャストされたポインターは同じアドレスを指します。(CPU にキャストを不可能にするアラインメントがない限り、それは未定義の動作です。)

つまり、実際のキャスト自体は問題ありません。データの操作を開始するとどうなるか... これは、別の実装定義の話です。

ここに標準からのものがあります:

「オブジェクトまたは不完全な型へのポインターは、別のオブジェクトまたは不完全な型へのポインターに変換される可能性があります。結果のポインターがポイント先の型に対して正しく整列されていない場合 (57)、動作は未定義です。それ以外の場合、変換されたとき再び戻ると、結果は元のポインタと等しくなります。

オブジェクトへのポインターが文字型へのポインターに変換されると、結果はオブジェクトの最下位アドレスのバイトを指します。オブジェクトのサイズまで結果を連続的にインクリメントすると、オブジェクトの残りのバイトへのポインタが生成されます。」

「57) 一般に、「正しく整列」という概念は推移的です: 型 A へのポインターが型 B へのポインターに対して正しく整列され、次に型 C へのポインターに対して正しく整列される場合、次へのポインター型 A は、型 C へのポインターに対して正しく整列されています。」

于 2011-01-21T14:37:04.547 に答える
0

私は質問に少し混乱していると思いますが、2番目と3番目の例は、オブジェクトの型を持つ左辺値を介してintにアクセスしています(int例では)。

C++ 3.10/15 は、最初の項目として、「オブジェクトの動的型」の型を持つ左辺値を介してオブジェクトにアクセスしても問題ないと述べています。

質問で私は何を誤解していますか?

于 2011-01-21T21:41:57.337 に答える