2014-02-25 26 views
2

我重新定义的sizeof为:为什么这个重新定义的sizeof作品

#undef sizeof 
#define sizeof(type) ((char*)((type*)(0) + 1) - (char*)((type*)(0))) 

对于这项工作,在定义2“0”必须是同一个实体在内存中,或者换句话说,需要有相同的地址。这是总是保证,还是编译器/体系结构/运行时间相关?

+2

我不明白为什么你感到吃惊的是这个工程。你似乎认为'0!= 0'是可能的。 –

+0

减法是必要的,所以我们正在处理一个指针差异(定义值)与一个原始指针(未定义的实际值) –

+1

这些'0' **是地址。 – alk

回答

1

0这里不是一个对象 - 它是一个地址。所以你问的问题是一个不太可靠的问题。

1

你在考虑零是需要存储在某个地方的谨慎数据。他们不是......他们被当作指向内存位置零的指针。

当你将一个指针增加到一个类型时,它实际上会增加它指向的类型的大小。这是C数组运算的工作原理。

0

一个严格符合标准的编译器可能会拒绝这个,或者返回一些废话。在“典型”的机器和指针具有相同的大小,并将一个整数转换为一个指针只需要该位模式,并将其视为一个指针。有些机器中的单词包含额外的数据(类型也许是权限位)。某些地址可能被禁止用于某些对象(即没有地址可以有地址0)等等。虽然可以保证sizeof(char) == 1,例如, Crays的字符实际上是32位。

此外,C标准保证sizeof(expression)中的expresison为而非评估完全,只是它的类型被采用。即,sizeof(x ++)doesn't increment x`。

+0

根据[本手册](http://docs.cray.com/books/004-2179-001/html-004-2179-001/rvc5mrwh.html),Cray'char'实际上是8位。尽管技术上允许使用该标准,但由于内存以字符计数,32位字符将成为C中的一个巨大问题。 – user4815162342

1

在实践中,某些类型的空指针总是指向内存中(的构造相同的方式尤其是当你做如上)相同的位置,只是因为任何其他的实现将是毫无意义的。

然而,该标准实际上并不保证了很多关于这一点:

  • “ [...]是保证比较不等于一个指向任何对象或函数” 6.3.2.3§3
  • “[...]任何两个空指针应比较相等。” 6.3.2.3§4

这留下了很多的李路。假设一个具有两个独特区域的记忆模型。每个区域可以有一个空指针区域(比如前128个字节)。很容易看出,即使在那个奇怪的情况下,关于空指针的基本假设确实可以成立!好吧,给定一个合适的编译器,使怪异的空测试...

那么,做什么别的,我们知道一般的指针...

你所要做的是第一,增加一个指针

“一个操作数应是指向一个完整的对象类型和其他应具有整数类型。(增加等效于将1)” [6.5。6§2]

然后指针差

“两个操作数都指向兼容完全对象类型的合格或不合格的版本” 6.5.6§3]

好的,他们是(好吧,假设type是一个完整的对象类型)。但是语义呢?

“对于这些操作符的目的,一个指针到一个对象,它是不是一个数组的元素的行为相同的指针长度的一个的阵列与作为对象的类型的所述第一元件其元素类型“。 [6.5.6§7]

这实际上有点问题:空指针不需要指向实际的对象! (否则你可以安全地解除引用...)因此,增加它或从另一个指针中减去它就是UB!

总之:0不指向一个对象,因此回答你的问题是第

+0

事实上,这是UB,尽管[链接](http://en.wikipedia.org/wiki/Undefined_behavior)或UB的一些解释会很好。 –

相关问题