编译时评估代码中的重言式是否保证被执行/优化掉?

mut*_*oid 0 c++ language-lawyer constexpr c++-concepts c++20

编译器是否保证评估环境constexpr"tautologies"(例如始终truefalse分别)的布尔表达式constexpr

最小示例/说明

例如,在以下代码片段(在标有 的行(1))中,我在constexpr环境中调用了一个函数,我打算在non-constexpr传递函数时导致编译时错误。至少我使用的编译器 ( g++-10.0) 是这样做的,即使它也可以意识到表达式总是true不计算它。我问这个问题的原因是 - 据我所知 - 在非 constepxr 上下文中,像这样的表达式i >= std::numeric_limits<int>::min()被优化trueint i.

#include <limits>
constexpr int example_function() { return 1;}
constexpr bool compileTimeErrorDesired = example_function() || true; // (1)
Run Code Online (Sandbox Code Playgroud)

应用实例

如果(1) 保证in 的行为,则可以在 aconcept中使用它,以执行不同的代码,具体取决于是否可以在编译时评估作为模板参数提供的函数。我实现了一个非常短的 ( 7 lines-of-code) 示例,它在编译器资源管理器中完全做到这一点。

如果使用非 constexpr 函数调用,行 (1) 是否保证会导致编译时错误?

编辑插入澄清,由于反馈而简化示例。

L. *_* F. 5

f() || true如果f不是 constexpr 函数,则保证它不是核心常量表达式:(常量表达式比核心常量表达式更具限制性)[expr.const]/2.2

一个表达式e是一个核心常量表达式除非的评价e如下所述抽象机的规则,将评估下列表达式之一:

  • [...]

  • 比constexpr构造为一个文字类,一个constexpr函数,或一个简单的析构函数的隐式调用其它的函数的调用([class.dtor])[ 注:?重载分析被照常应用- 注完 ];

  • [...]

如果在需要常量表达式的上下文中使用非常量表达式,还可以保证程序格式错误(需要诊断)。注意||定义为从左到右求值:[expr.log.or]/1

||左到右操作员组。操作数都根据上下文转换为bool. true如果其任一操作数为truefalse则返回,否则返回。与 不同|||保证从左到右求值;此外,如果第一个操作数的计算结果为真,则不会计算第二个操作数。

换句话说,true || f()是一个核心常量表达式,因为f()没有被评估,而f() || true不是因为f()被评估。

表达式是否为常量表达式与优化无关——常量表达式是根据抽象机器的规则定义的。