C ++中编译时和运行时运算符的定义是什么?
我知道sizeof()
是C ++中的编译时运算符,但它是运行时运算符?
(Originally posted c c++ bc90 {{3}}我不想浪费我发布的答案,之后才明白他只想要一个C回答。嘿,也许这可以帮助"澄清"某人"怀疑"有一天。)
答案 0 :(得分:12)
它并不那么简单。没有"运行时运算符列表"或"编译时运算符列表"。有运算符,其中许多可以优化为"执行"由编译器而不是作为要在运行时执行的操作编码到程序中。
显而易见的是sizeof
,在程序执行之前,从不需要推迟。实际上,一般来说,作用于类型的操作符可能是纯粹的语义操作,不依赖于运行时信息。另一个例子是,const_cast
绝对没有理由拥有任何运行时相关性,因为const
在编译的程序中甚至不存在。可以优化static_cast
,但这取决于相关转换运算符的作用。
可能不那么明显的是,许多调用算术运算符的表达式可能会被优化掉。
例如:
const int x = 2 + 4;
除非您的编译器非常非常愚蠢,否则不会在运行时执行此添加。但这是否使operator+
成为编译时运算符"?否。
如果适用的()
规则适用,或者函数定义在与调用站点相同的转换单元中可见,则函数调用操作符constexpr
在编译时才会被调用。并且是非常微不足道的。
虽然我们处于此状态,但reinterpret_cast
取消了表达式constexpr
的资格。这是相当不直观的,但根据CWG issue #1384中的基本原理:
虽然在C ++ 03中的地址常量表达式中允许
reinterpret_cast
,但是这种限制已在某些编译器中实现,并且未证明会破坏大量代码。 CWG认为处理tpes [sic] 改变的指针的复杂性(指针算术和取消引用在这些指针上是不允许的)超过了放宽当前限制的可能效用。
我的观点是,实际上,不值得尝试为此提出一般规则:C ++程序编译的过程只是而不是那么简单。您必须根据具体情况检查您的计划正在做什么。
但是,我很感激您正在尝试回答一个糟糕的考试问题。为此,你有同情心。