Him*_*rav 9 c struct casting offsetof
我在一本书中找到了这个代码示例,但是我无法理解printf语句中的表达式.并且这个程序成功编译输出为4.友好建议...
void main(){
unsigned char c;
typedef struct name {
long a;
int b;
long c;
}r;
r re = {3,4,5};
r *na=&re;
printf("%d",*(int*)((char*)na + (unsigned int ) & (((struct name *)NULL)->b)));
}
Run Code Online (Sandbox Code Playgroud)
让我们从最后一行开始:
printf("%d",*(int*)((char*)na + (unsigned int ) & (((struct name *)NULL)->b)));
Run Code Online (Sandbox Code Playgroud)
让我们解读:
(unsigned int ) & (( (struct name *)NULL)->b )
Run Code Online (Sandbox Code Playgroud)
实际上是铸成& (( (struct name *)NULL)->b )了一个unsigned int.
& (( (struct name *)NULL)->b ) 是地址(即它给出一个指针):
(( (struct name *)NULL)->b )
Run Code Online (Sandbox Code Playgroud)
这实际上是b(as name.b)从NULL(0)的偏移量,它是4个字节(假设a long是4个字节)并转换为int的指针,给出2(假设int是2个字节).
如果不是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,因为它然后使用相同的偏移来获得值.