2016-10-06 18 views
1

時々、C++コンパイラは同じバイナリ内の同じタイプTに対して異なるメモリレイアウトを生成します。すなわち、オブジェクトは、クラスの非連続サブオブジェクトとして、スタンドアロンオブジェクト又はアレイサブオブジェクトの両方として発生したときにこれが起こる:同じバイナリで同じタイプの異なるレイアウト

struct A { int i; }; 
struct B : virtual A { int i; }; 
struct C : virtual A { int i; }; 
struct D : B,C { int i; }; 
... 
D d; 
B b; 
B* p1= &(B&)d; 
B* p2= &b; 

C++ 14標準によれば、任意のものを生成するフリーのコンパイラであります1つのバイナリ内にタイプTのオブジェクトの異なるレイアウトの数? メモリレイアウトはコンパイル時に固定されていますか?

スピン・オフ:2番目の質問にHow does placement new know which layout to create?


詳細説明: 型TのオブジェクトtはT *でまたはchar *ポインタのいずれかによってアクセスすることができます。 (後者は3.10(10)によって正当化される)コンパイルされたプログラムが実行されると、一方はチャーポインタを介してTにアクセスすることにより、Tのサブオブジェクトの相対オフセットを決定してもよいです。これらのオフセットは決定的なものか、あるプログラムの実行から別のプログラムの実行に変わることがありますか?

+0

ご質問を詳しくお答えください。 *メモリレイアウトはコンパイル時に固定されていますか? –

答えて

2

C++ 14の標準によれば、クラスへのポインタを別のものへのポインタに変換してからポインタを使用すると、UBが得られます。したがって、クラスの先頭からオフセットしてクラスポインタを追加することはできません。

標準レイアウトオブジェクトでは、より多くの保証が得られ、offsetofを使用して確定的な結果を得ることができます。仮想継承を持つクラスは難しいことであり、間違いなく標準レイアウトのクラスではありません。

+0

UBクレームをサポートする引用符を提供してもらえますか? UBの結果となるキャストがいくつかありますが、私はこれが大丈夫だと考えます。 ((char *)(void *)&t) –

+0

キャスト自体は問題ありません。任意のポインタをキャストすることができます(注:ビジュアルスタジオポインターでは、仮想継承を持つクラスのメソッドへのポインタが大きくなります)。しかし、あなたがこのようなキャストされたポインタを使って行うことができるのは、それをコピーするか元の型にキャストすることだけです。 UBはキャストポインタには存在しませんが、実装の詳細であるクラスレイアウトの前提にあります。 –

+0

あなたはUB =未定義、または未指定を意味しますか?今、ランダムな乱数をファイルに書き込むことは明らかに未定であり、生のメモリを書き込むことはそれほど重要ではありません。 (標準は、非決定論的抽象機械について話していることを非常に明確にしています)、これがどこでプログラム全体を無効にする未定義の動作に低下するかわかりません。標準では、* pがcharポインタpの意味を指定しています。 (§5.3.1.1、§3.10.10) –

0

予備的な答え(今のところ、付与されたためにこれを取ることはありません):

のは、Tは、少なくとも二つの非静的データメンバを持つクラス型であると仮定しましょう。 Tが標準レイアウトクラスでない場合、2つのデータメンバーが公開アクセス権と非公開アクセス権を持っていると仮定します。以下で説明するレイアウトは、標準によって課せられた順序付けおよび連続性要件を満たすことが理解される。

a)Tが容易にコピー可能でも標準レイアウトでもない場合、T型のオブジェクトが作成されると、実装は乱数ジェネレータを使用して新しいメモリレイアウトを自由に作成できます。 1つのバイナリによって作成される可能性のあるTの異なるメモリレイアウトの数に上限はありません。

b)Tが普通にはコピーできますが、標準のレイアウトではない場合、実装では、プログラムの開始時に乱数ジェネレータを使用してレイアウトを生成することは自由です(標準では何もありません)可能なレイアウトの数は有限です。レイアウトは、プログラムの実行ごとに異なる場合があります。 (§3.9.2および§1.8.5による制限)

c)Tが標準レイアウトである場合、考えられるレイアウトは1つだけです。 (注文と隣接性が保証されています)

関連する問題