最後の行から始めましょう:
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.blongint
代わりに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 を出力する必要があります。