为什么sizeof实现为运算符而不是宏

时间:2014-08-14 06:29:30

标签: c macros sizeof unary-operator

我理解为什么sizeof没有作为Why is sizeof considered as an operator?

中的函数实现的原因

但我不明白为什么我们需要将sizeof实现为特殊类型的unary operator,它作为编译时而不是运行时执行(我猜因为其他运算符总是作为运行时执行)< / p>

我们可以通过将sizeof设为macro 不是来实现同样的目标。这些compiled time unary operatormacros之间有什么区别?


我只是想知道为什么他们不首先考虑宏而不是实现不同的运算符。当我第一次想到sizeof()时,我认为它应该是宏观的。没想到这样的一元经营者。

3 个答案:

答案 0 :(得分:6)

你的问题并非毫无根据。实际上,标准库已经具有与宏实现的非常相似的特性:它是标准的offsetof宏。另请注意,sizeof的可用性的很大一部分来自其编译时性质(对于offsetof也是如此),这就是运行时实现明显较差的原因。 (而且,顺便说一句,你的断言声明声称所有其他运算符都是&#34;总是在运行时执行&#34;完全是不真实的。)

即使在原始C语言中,sizeof无法作为宏实现的一个原因是它应该同时接受类型表达式作为参数。使用单个宏来覆盖这两种参数是不可能的。我们至少需要两个宏:一个用于类型,一个用于表达式。但即使我们同意将这两种形式的sizeof分成两个不同的宏,实现一个能够正确处理表达式参数的宏仍然是相当困难的(甚至是不可能的)。

同时,如果我们将自己局限于原始C(即从考虑C99 VLA中排除),那么我们可以将类型参数的sizeof实现为宏

#define sizeof(T) ((size_t) ((T *) 0 + 1))

这与用于将标准offsetof实现为宏的技术几乎相同。

上面的宏实现仍然不完美,因为它不适用于int[6]参数,但你明白了。 BTW可能是支持内置运算符实现而不是宏的另一个点。

但是如何为表达式参数做同样的事情 - 我不知道。你呢?

答案 1 :(得分:3)

宏由预处理器处理。运算符由编译器处理。

虽然预处理器可以轻松确定sizeof(int),但请考虑sizeof(MyCustomStruct)。为了评估它,我们必须知道MyCustomStruct的结构,它只由编译器评估。

编译时间超过运行时间的优势当然是性能。如果你可以在编译时做一次,为什么要在运行时多次这样做?

答案 2 :(得分:1)

  

其他运算符始终作为运行时执行。

事实并非如此;常量表达式中的运算符在编译时进行计算。例如,15 * 60是评估的编译时间。除了在C99中引入的VLA之外,sizeof运算符表达式按定义是常量,因此始终在编译时进行求值。