c – 编译器是否强制拒绝无效的constexpr?

#include <exception>

constexpr bool foo(bool x)
{
  return x ? true : throw std::exception();
}

int main()
{
  // 1) must never be compiled
  // static_assert(foo(false),"");

  // 2) must always be compiled?
  const bool x = foo(false);

  // 3) must never compile?
  constexpr bool y = foo(false);

  return 0;
}

我确定(1)必须导致编译错误.我确信(2)在编译时不能被拒绝,尽管它在运行时会失败.

有趣的情况是constexpr变量(3).在这个简单的例子中,gcc和clang实际上会评估表达式,因此拒绝程序. (错误信息:y不是常量表达式).

每个C11编译器是否强制拒绝该程序?如果foo(false)被更复杂的表达式所替代,该怎么办?

我惊讶地发现,constexpr并不完整,尽管它将在规范的改变之后:
Is constexpr-based computation Turing complete?

也许这与我的问题有关.据我所知,在本例中,编译器被允许推迟对constexpr(3)的实际评估,直到运行时为止.但是,如果constexpr是完整的,我发现很难相信编译器可以决定所有的constexpr是否会抛出异常(这意味着constexpr无效).

解决方法

通过我的阅读,是的,每个编译器都必须抱怨声明(3).

N3242 7.1.5第9段:

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. If it initialized by a constructor call,that call shall be a constant expression (5.19). Otherwise,every full-expression that appears in its initializer shall be a constant expression. Each implicit conversion used in converting the initializer expressions and each constructor call used for the initialization shall be one of those allowed in a constant expression (5.19).

我认为一个constexpr对象为“在编译时评估”,并且一个constexpr函数或者constexpr构造函数可能在编译时被评估.编译器必须在编译时确定(3)这样的语句的语义有效性.您可以认为“评估”仍然可以在运行时完成,但检查有效性大部分都是正常工作.此外,代码可以继续实例化一个像“检查”一样的模板,这几乎可以保证编译器需要在编译时找出y的值.

这的确意味着你可以编写一个恶作剧程序来使编译器花费很长的时间或无限的时间.但是我怀疑已经有可能与运算符 – >招数.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...