最後の行から始めましょう:
printf("%d",*(int*)((char*)na + (unsigned int ) & (((struct name *)NULL)->b)));
解釈しましょう:
(unsigned int ) & (( (struct name *)NULL)->b )
実際に にキャスト& (( (struct name *)NULL)->b )
していunsigned int
ます。
& (( (struct name *)NULL)->b )
アドレスです(つまり、ポインタを提供します):
(( (struct name *)NULL)->b )
これは実際にはNULL (0) からのb
(as ) のオフセットであり、4 バイト (aが 4 バイトであると仮定) であり、int のポインターに変換されると、2 ( 2 バイトであると仮定) になります。name.b
long
int
代わりにNULL
へのポインターだった0xFFFF0000
場合は、 に&(ptr->b)
なります0xFFFF0002
。しかし、それはもっと&(0 -> b)
そう0x00000002
です。
つまり、(unsigned int ) & (( (struct name *)NULL)->b ) == 2
(マシンによっては 1 つ、または 4 つかもしれません)。
残りは簡単です:*(int*)((char*)na + 2
を指しre->b
ます。したがって、4 (コードで初期化されたものr re ={3,4,5};
) が出力されます。
PS: (unsigned int ) & (( (struct name *)NULL)->b ) != 2
(おそらく 1、4、または 8 の場合でも) - 同じオフセットを使用して値を取得するため、4 を出力する必要があります。