C++ 中的运行时运算符

Posted

技术标签:

【中文标题】C++ 中的运行时运算符【英文标题】:Run-time operators in C++ 【发布时间】:2015-05-11 10:22:14 【问题描述】:

C++中编译时和运行时运算符的定义是什么?

我知道sizeof() 是 C++ 中的编译时运算符,但哪些是运行时运算符?


(Originally posted for cc++ by bc90; 在明确他只想要一个 C 答案之前,我不想浪费我发布的答案。嘿,也许这可以帮助有一天“澄清”某人的“疑虑”。)

【问题讨论】:

【参考方案1】:

事情没有那么简单。没有“运行时运算符列表”或“编译时运算符列表”。有操作符,其中许多可能被优化为由编译器“执行”,而不是作为在运行时执行的操作编码到程序中。

显而易见的是sizeof从不需要推迟到程序执行。事实上,一般来说,作用于 types 的操作符可能被认为是纯粹的语义操作,不依赖于运行时信息。再举一个例子,const_cast 绝对没有理由与任何运行时相关,因为 const 甚至不存在于您编译的程序中。 static_cast 可能会被优化掉,但这取决于相关的转换操作符做什么。

可能不太明显的是,许多调用算术运算符的表达式可能会被优化掉。

例如:

const int x = 2 + 4;

除非您的编译器非常非常愚蠢,否则不会在运行时执行该添加。但这会使operator+ 成为“编译时运算符”吗?没有。

并且函数调用运算符 () 只有在适用的 constexpr 规则适用时才能在编译时被调用,或者函数定义在与调用站点相同的翻译单元中可见并且足够简单.

虽然我们正在这样做,但reinterpret_cast 会取消表达式作为constexpr 的资格。这是相当不直观的,但根据CWG issue #1384 中的基本原理:

尽管reinterpret_cast 在 C++03 中的地址常量表达式中是允许的,但此限制已在某些编译器中实现,并且未证明会破坏大量代码。 CWG 认为,处理 tpes [sic] 发生变化的指针(不允许对此类指针进行指针算术和取消引用)的复杂性超过了放宽当前限制的可能效用。

我的观点是,真的,不值得为此尝试提出一般规则:C++ 程序编译的过程只是那么简单。您必须逐个检查您的程序在做什么。

但是,我非常感谢您尝试回答一个糟糕的考试问题。对此,你有我的同情。

【讨论】:

奇怪的是reinterpret_cast 取消了表达式constexpr 的资格 是的,真的:N4296 [expr.const]/2.13 @TemplateRex:并不是我不相信你。知道为什么吗? @TemplateRex gcc 和 clang 都允许异常 using __builtin_constant_p ... 很神奇 评论让我笑了。

以上是关于C++ 中的运行时运算符的主要内容,如果未能解决你的问题,请参考以下文章

使用 -> 运算符后 C++ 程序崩溃

使用数组重载运算符“=”会导致运行时错误 C++

C++中的运算符“”是啥?

三元运算符

C++ 中的指针成员 ->* 和 .* 运算符是啥?

算术 C++ 运算符