私はこのようなことをしたい:
union U {
int i;
double d;
};
void foo (double *d) { *d = 3.4; }
int main ()
{
union U u;
foo (&(u.d));
}
gcc
は(で)文句を言わず-Wall -Wextra
、期待どおりに機能しますが、実際に合法であることを確認したいと思います(標準に従って)。
なぜそれは合法であるべきではないのですか?実際には、すべてのメンバーのアドレスがユニオン全体のアドレスと等しいことが保証されています。
適切に変換された共用体オブジェクトへのポインタは、その各メンバー[...]を指し、その逆も同様です。
(C11、§6.7.2.116)
(これは、ユニオンメンバーへのポインターを取得できることを意味します)
はい、これは合法であり、そうでない理由はありません。そのような単純な。
C99:
6.5.3.2
アドレスおよび間接演算子
制約
- 単項&演算子のオペランドは、関数指定子、[]または単項*演算子の結果、またはビットフィールドではなくレジスタストレージクラス指定子で宣言されていないオブジェクトを指定する左辺値のいずれかでなければなりません。
[...]
実行環境のデータストレージのオブジェクト 領域。その内容は値を表すことができます。
したがって、はい、ユニオンはオブジェクトであるため、他の要件を満たしている限り、&のオペランドになる可能性があります。