例えば
union
{
int n;
void *p;
} u;
un の初期値または up の初期値は 0 ですか?
NULL ポインターは必ずしもすべてゼロのビットに格納されるとは限らないことに注意してください。そのため、unとupが同じ大きさであっても、
u.n == 0
保証しません
u.p == 0
およびその逆。
(下手な英語でごめんなさい)
例えば
union
{
int n;
void *p;
} u;
un の初期値または up の初期値は 0 ですか?
NULL ポインターは必ずしもすべてゼロのビットに格納されるとは限らないことに注意してください。そのため、unとupが同じ大きさであっても、
u.n == 0
保証しません
u.p == 0
およびその逆。
(下手な英語でごめんなさい)
静的ストレージ期間を持つオブジェクトが明示的に初期化されていない場合:
— ポインター型の場合、null ポインターに初期化されます。
— 算術型の場合、(正または符号なし) ゼロに初期化されます。
— 集合体の場合、すべてのメンバーはこれらの規則に従って (再帰的に) 初期化されます。
— 共用体の場合、最初の名前付きメンバーは、これらの規則に従って (再帰的に) 初期化されます。
したがってu.n
、ゼロに初期化され、u.p
未定です。
編集: コメントへの応答
ISO/IEC 9899:201x 6.7.9.10からコピーされた上記の情報
u
は静的であるため、最初のメンバーは、C99 ドラフト標準セクションの初期化段落10zero
からに初期化されます。6.7.8
自動保存期間を持つオブジェクトが明示的に初期化されていない場合、その値は不確定です。静的ストレージ期間を持つオブジェクトが明示的に初期化されていない場合:
— ポインター型の場合、null ポインターに初期化されます。
— 算術型の場合、(正または符号なし) ゼロに初期化されます。
— 集合体の場合、すべてのメンバーはこれらの規則に従って (再帰的に) 初期化されます。
— unionの場合、最初に指定されたメンバーがこれらの規則に従って (再帰的に) 初期化されます。
はn
であるため、arithmetic type
に初期化されzero
ます。の値は指定されていませんが、実際には型パニングp
は通常、コンパイラによってサポートされています。
最後に書き込まれたものとは異なるユニオン メンバーから読み取る (「タイプ パニング」と呼ばれる) 慣行は一般的です。-fstrict-aliasing を使用しても、union 型を介してメモリにアクセスする場合は、型パニングが許可されます。
may
次のように、ユニオンの任意のメンバーを初期化できることにも注意してください。
union { int n; void *p; } u = { .p = NULL } ;
^^^^^^^^^^^^^
ただし、すべてのコンパイラがこれをサポートしているかどうかはわかりません。
「グローバル変数」とは、ファイルスコープにあることを意味すると思います。その場合、それが「静的」と宣言されている場合、.BSS で割り当てられるなどの理由で、すべてゼロのビットに初期化されます。アクセスするメンバーの値に関して、ユニオンのストレージ内のゼロビットが何を意味するかは、それらのタイプによって異なります。あなたの場合、intのすべてのゼロビットは値がゼロであることを意味し、ポインターのすべてのゼロビットはそれをNULLにします。つまり、ここで@Dukelingの強打です。float のすべての 0 ビットが値 0 の float を生成するかどうかはわかりません。