我在书中某处看到了这个复杂的 sizeof 运算符声明,这在取笑我:
#define SIZEOF(int) (int)&((int *)0)[1]
任何人都可以解释这个声明,这里发生了什么......?
我在书中某处看到了这个复杂的 sizeof 运算符声明,这在取笑我:
#define SIZEOF(int) (int)&((int *)0)[1]
任何人都可以解释这个声明,这里发生了什么......?
这是[1]
“扩展”部分:
(int)(&(*(((int*)0) + 1)))
现在你明白它是如何工作的了吗?
sizeof
int
由于指针算术的属性,0 将增加,最后的转换int
为您提供结果地址的值,即“大小”。
这是完全未定义的行为(null 的算术,可能还有无效指针的取消引用),相当没有意义。
用宏参数更新没有多大意义。最后的演员应该是std::uintptr_t
。
首先 - 它与术语混淆int
- 我们自然假设它是熟悉类型的关键字,但在这种情况下它不是 - 相反,它是宏的参数。所以为了简化,考虑如下宏:
#define SIZEOF(type) &((type *)0)[1]
现在这样看,可能更容易看出宏首先将地址 0 转换为指向 的指针type
,然后获取第二个元素的地址。这将显示大小。
它定义SIZEOF
为整数的大小。
(int *)0
是地址为零的 int 指针[1]
访问该整数之后的下一个整数。(int *)0
地址为零,因此它之后的地址sizeof int
正好位于前一个地址之后。(int)
将其转换为数字,因为大小是数字,而不是指针。显然这是一个讨厌的黑客,应该简单地使用sizeof int
.