我正在将sizeof重新定义为:
#undef sizeof
#define sizeof(type) ((char*)((type*)(0) + 1) - (char*)((type*)(0)))
为此,定义中的2'0'需要与内存中的实体相同,换句话说,需要具有相同的地址。这总是有保证,还是编译器/体系结构/运行时依赖?
答案 0 :(得分:1)
这里的0
不是对象 - 它是一个地址。所以你提出的问题是一个不合理的问题。
答案 1 :(得分:1)
您认为零是需要存储在某处的谨慎的数据片段。它们不是......它们被作为指向内存位置零的指针。
当您将指针递增到某个类型时,它实际上会增加它指向的类型的大小。这就是C数组算法的工作原理。
答案 2 :(得分:1)
实际上,某种类型的空指针总是指内存中的相同位置(特别是当构造方式与上面相同时),因为任何其他实现都是毫无意义的。
然而,标准实际上并不能保证很多:
这留下了许多背风。假设具有两个不同区域的存储器模型。每个区域可以有一个空指针区域(比如前128个字节)。很容易看出,即使在那种奇怪的情况下,关于空指针的基本假设确实可以成立!好吧,给定一个适当的编译器,使奇怪的空测试......
那么,我们对指针一般还有什么了解......
你要做的是先增加一个指针
“一个操作数应该是指向完整对象类型的指针,另一个操作数应该是整数类型。(递增相当于添加1.)”[6.5.6§2]
然后是指针差异
“两个操作数都是兼容完整对象类型的限定或非限定版本的指针”[6.5.6§3]
好的,它们是(好吧,假设类型是完整的对象类型)。但是语义呢?
“出于这些运算符的目的,指向不是数组元素的对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型“。 [6.5.6§7]
这实际上有点问题:空指针不需要指向实际对象! (否则你可以安全地取消引用它...)因此,增加它或从另一个指针中减去它是UB!
总结:0
未指向某个对象,因此您的问题的答案为否。
答案 3 :(得分:0)
严格符合标准的编译器可以拒绝这一点,或者返回一些废话。在“典型”机器和指针上具有相同的大小,并且向指针投射整数只是采用该位模式并将其视为指针。有些机器中的单词包含额外的数据(类型可能是权限位)。对于某些对象可能禁止某些地址(即,没有任何地址可以具有地址0),等等。虽然可以保证sizeof(char) == 1
,例如Crays一个字符实际上是32位。
此外,C标准保证sizeof(expression)
中的表达式不根本不进行评估,仅采用其类型。即,^ sizeof(x ++)doesn't increment
x`。