6

ISO / IEC 9899:TC2では、規格は次のように述べています

6.3.2.3ポインター

  1. オブジェクトまたは不完全な型へのポインタは、別のオブジェクトまたは不完全な型へのポインタに変換される場合があります。結果のポインタがpointed-toタイプに対して正しく整列されていない場合、動作は定義されていません。それ以外の場合、再度変換すると、結果は元のポインターと同じになります。オブジェクトへのポインタが文字型へのポインタに変換されると、結果はオブジェクトの最下位アドレスバイトを指します。オブジェクトのサイズまでの結果の連続的な増分は、オブジェクトの残りのバイトへのポインターを生成します。

したがって、あるタイプのポインタを別のタイプのポインタにキャストできることは、標準からは明らかではありません。

4

1 に答える 1

14

厳密なエイリアシングルールは別の場所で定義されています。これは言い回しです:

C(ISO / IEC 9899:1999 6.5 / 7):

オブジェクトは、次のいずれかのタイプの左辺値式によってのみ、格納された値にアクセスする必要があります。

  • オブジェクトの有効なタイプと互換性のあるタイプ、
  • オブジェクトの有効なタイプと互換性のあるタイプの認定バージョン、
  • オブジェクトの有効な型に対応する符号付きまたは符号なしの型である型、
  • オブジェクトの有効な型の修飾されたバージョンに対応する符号付きまたは符号なしの型である型、
  • メンバーの中に前述のタイプの1つを含む集合体または共用体タイプ(再帰的に、サブ集合体または含まれる共用体のメンバーを含む)、または
  • 文字タイプ。

C ++(ISO / IEC 14882:2011 3.10 [basicl.lval] / 15):

プログラムが次のタイプのいずれか以外の左辺値を介してオブジェクトの格納された値にアクセスしようとした場合、動作は未定義です。

  • オブジェクトの動的タイプ、
  • オブジェクトの動的タイプのcv修飾バージョン。
  • オブジェクトの動的タイプに類似したタイプ(4.4で定義)、
  • オブジェクトの動的型に対応する符号付きまたは符号なしの型である型、
  • オブジェクトの動的型のcv修飾バージョンに対応する符号付きまたは符号なし型である型。
  • 要素または非静的データメンバー(再帰的に、サブアグリゲートまたは含まれるユニオンの要素または非静的データメンバーを含む)の中に前述のタイプの1つを含む集合体または共用体タイプ。
  • オブジェクトの動的型の(おそらくcv修飾された)基本クラス型である型、
  • charまたはunsigned charタイプ。

C標準では、アラインメントの問題がない限り、ポインタを無関係の型にキャストすることを禁止していません。ただし、厳密なエイリアシング規則により、基本的に、そのようなキャストから取得したポインターを逆参照することはできません。したがって、このような「無効な」ポインタを使用する場合に役立つのは、正しい型(または互換性のある型)に戻すことだけです。

これは、reinterpret_cast(5.2.10 [expr.reinterpret.cast] / 7)を使用したC++でもほとんど同じです。

オブジェクトポインタは、別のタイプのオブジェクトポインタに明示的に変換できます。タイプ「pointerto」のprvaluevがタイプ「pointertocvT1」に変換されると、結果は、とが両方とも標準レイアウトタイプ(3.9)であり、の配置要件がのそれらよりも厳密でない場合、またはいずれかのタイプの場合になります。です。タイプ「pointerto」のprvalueをタイプ「pointerto 」(ここで、およびはオブジェクトタイプであり、の配置要件はの要件よりも厳密ではありません)に変換し、元のタイプに戻すと、元のポインタ値が生成されます。他のそのようなポインタ変換の結果は指定されていません。 T2static_cast<cv T2*>(static_cast<cv void*>(v))T1T2T2T1voidT1T2T1T2T2T1

于 2011-09-03T07:58:32.217 に答える