首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >编译时评估的代码中的重言式是否保证被执行/优化?

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

Stack Overflow用户
提问于 2020-03-24 12:51:56
回答 2查看 156关注 0票数 0

编译器是否保证计算布尔constexpr表达式,即在constexpr环境中为"tautologies" (例如总是truefalse )?

最少的例子/澄清

例如,在下面的代码片段(标记为(1)的行)中,我在constexpr环境中调用一个函数,每当传递non-constexpr函数时,它都会导致编译时错误。至少我使用的编译器(g++-10.0)可以做到这一点,尽管它也可以意识到表达式总是true,而不需要计算它。我之所以问这个问题,是因为--据我所知--在一个非连续的上下文中,像i >= std::numeric_limits<int>::min()这样的表达式被优化为true,用于int i

代码语言:javascript
复制
#include <limits>
constexpr int example_function() { return 1;}
constexpr bool compileTimeErrorDesired = example_function() || true; // (1)

应用实例

如果保证了(1)中的行为,例如可以在concept中使用它,以便执行不同的代码,这取决于作为模板参数提供的函数是否可以在编译时进行计算。我实现了一个非常短的(7 lines-of-code)示例,它正好实现了在编译器资源管理器

问题

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-24 13:34:36

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

表达式e是一个核心常量表达式,除非对e的计算遵循抽象机器的规则,将计算(以下表达式之一):

  • ..。
  • 对文字类的constexpr构造函数以外的函数的调用,对constexpr函数的调用,或对平凡析构函数(class.dtor)的隐式调用--注意:重载解析与通常的 -end applied注释相同;
  • ..。

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

||运算符从左到右分组.操作数都在上下文上转换为bool。如果它的任一操作数为true,则返回false,否则返回false。与|不同,||保证从左到右的计算;此外,如果第一个操作数计算为真,则不计算第二个操作数.

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

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

票数 5
EN

Stack Overflow用户

发布于 2020-03-24 13:47:54

对于常量表达式,“已执行”一词并不完全合适。即使是“评估”也可以谨慎使用,因为表达式是否是常量表达式在一定程度上取决于如果对表达式进行评估会发生什么行为,但在最严格的意义上并不被认为是一种评估。

[expr.const]描述了“编译时行为”的许多不同上下文的需求,包括“常量表达式”。expr.const/(5.2)说,如果计算一个表达式将计算一个非参数函数,则表达式不是一个核心常量表达式,因此不是一个常量表达式。如果表达式在需要常量表达式的上下文中使用(如static_assert、非类型模板参数等),则程序格式不正确,必须有诊断消息。没有任何规则允许在这样的上下文中允许非常数表达式,或者跳过假设计算的某些部分,如果表达式是转换的常量表达式,并且表达式的结果值可以确定,尽管它不是常量表达式。

因此,如果example_function未声明为constexpr,则example_function() || true不是常量表达式,因为计算将要求调用该函数。但是true || example_function()是一个常量表达式,因为计算不会调用该函数。

您的is_constexpr<T>可以保证工作,因为任何涉及需求表达式中的模板参数的语义约束冲突都不会使程序格式不正确,而只是使需求表达式结果值false ([expr.prim.req]/6)。在is_constexpr<example_function>中,使用非常量表达式T()作为模板参数,通过ConstexprHelper<T>实例化的默认模板参数对std::enable_if来说是一个语义错误,因此requires表达式具有值false

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60831438

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档