我理解为什么sizeof
没有作为Why is sizeof considered as an operator?
但我不明白为什么我们需要将sizeof实现为特殊类型的unary operator
,它作为编译时而不是运行时执行(我猜因为其他运算符总是作为运行时执行)< / p>
我们可以通过将sizeof设为macro 不是来实现同样的目标。这些compiled time unary operator
和macros
之间有什么区别?
我只是想知道为什么他们不首先考虑宏而不是实现不同的运算符。当我第一次想到sizeof()时,我认为它应该是宏观的。没想到这样的一元经营者。
答案 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
运算符表达式按定义是常量,因此始终在编译时进行求值。