4
int i = 42;
int *p1 = &i;
int long *p2 = (long*)p1;

これは未定義の動作ですか?C ++では、何らかの理由で実装定義の動作だと思います。

私はCスタンダードで調べました:

C99 6.3.2.3 / 7オブジェクトまたは不完全な型へのポインタは、別のオブジェクトまたは不完全な型へのポインタに変換される場合があります。結果のポインタがポイント先の型に対して正しく整列されていない場合57)、動作は定義されていません。それ以外の場合、再度変換すると、結果は元のポインターと同じになります。

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

ここで正しく整列されたという用語は、実際にはどういう意味ですか?未定義動作に踏み込むことなく正しく実行しているかどうかをどうやって知ることができますか?

4

1 に答える 1

4

これは基本的に、たとえばint4バイトにint longアラインされ、8バイトにアラインされた場合、動作は未定義であることを意味します。次のようなものがあるとします。

 0x04     0x08    0x0C    0x10
+------+-------+-------+-------+
|      |       |   i   |       |
+------+-------+-------+-------+

この場合、 ( 4バイトにアラインされて&i == 0x0Cいるため有効です)。intにキャストするint long*と、ポインタは整列されたものに変換されp2 == 0x08ます。理論上のシステムはint long8バイトに整列するため、逆参照すると、基本的に所有していないアドレスを読み取ることになりp1、未定義の動作が発生します。

于 2012-12-04T04:47:55.770 に答える