2011-11-20 8 views
4

私はこのような標準レイアウトのタイプがある場合:このようなユニオンは標準レイアウト型ですか?

struct sl_t 
{ 
    int a; 
}; 

とユニオン:

union un_t 
{ 
    int b; 
    double q; 
}; 

私はキャストし、構造体の型として組合を使用することはできますか?つまり、私は、共用体そのものが標準レイアウト型で、データがメモリの先頭に配置されていると仮定してもよいでしょうか?

un_t obj; 
sl_t * s = reinterpret_cast<sl_t*>(&obj); 
s->a = 15; 
assert(obj.b == 15); 

または私は労働組合&obj.bにおける変数のアドレスを取る必要がありますか?

私が既に知っているのは、構造体をアセンブリ内に格納すると、C++ 11標準では9.5-1を参照してsl_t :: aとun_t :: bの両方にアクセスできることを保証していることに注意してください。

+2

...「&obj.b」はもっと短く安全ですか?私はあなたの動機が不思議です。 –

+0

私はまだ実際にはその周りにreinterpret_castが必要です。私は主に興味がありますが、実際にはこれに頼るのが便利なケースがあります。 –

答えて

3

見た目の整合性が問題視される場合は、pragma packをご覧ください。構造体/共用体の名前は割り当てられたメモリブロックを参照するだけです.st_t.aが構造体の中でより多くのメンバを追加することで置き換えられた場合、キャストは失敗しますが、最初のメンバのままであれば、共用体そのものと同じアドレス。

C++標準の9.2.17 - 21節を参照してください。 "reinterpret_castを使って適切に変換された標準レイアウトのstructオブジェクトへのポインタは、その最初のメンバを指しています(またはそのメンバがビットフィールド、それが存在するユニットへ)、逆もまた同様である。 、非静的データメンバの最大1つは、任意の時点でアクティブにできる、つまり、非静的データの最大1つの値である労働組合で 「1:

もセクション9.5労働組合を参照してください。 [注:共用体の使用を簡略化するために特別な保証が1つあります。標準レイアウトの共用体に共通の初期シーケンス(9.2)を持つ複数の標準レイアウト構造体が含まれている場合、この標準レイアウト構造体のオブジェクトに標準レイアウト構造体のいずれかが含まれている場合、標準レイアウト構造体メンバのいずれかの共通初期シーケンスを検査することが許される; 9.2を参照 - end note]各非静的データメンバーは、それが構造体の唯一のメンバーであるかのように割り当てられます。

+0

私は、それが有効であるかどうか、コンパイラの拡張子なしで、知っていることに興味があります。 –

+0

@ edA-qa mort-ora-y:答えを拡大しました。はい、有効ですが、説明したとおりです。 – slashmais

+1

2番目のコメントは、標準で実際に組合員の住所がアドレス自体と同じであることを保証していますか?それは私が見つけられなかったことですが、はい、それは私の変換を有効にするでしょう。そして確かに、st_t.aがもはや最初のメンバーではない場合、明らかに動作しません。 –

関連する問題