- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
#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 不是常量表达式)。
是否每个 C++11 编译器都被迫拒绝该程序?如果将 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 asconst
. 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) 这样的语句的语义有效性。您可能会争辩说“评估”仍然可以在运行时完成,但是检查有效性无论如何都会完成大部分工作。另外,代码可以继续实例化一个模板,如 Check<y>
,这几乎可以保证编译器需要计算出 y
的值在编译时。
这确实意味着您可以编写一个邪恶的程序来使编译器花费很长时间或无限的时间。但我怀疑 operator->
已经可以实现了技巧。
关于c++ - 编译器是否被迫拒绝无效的 constexpr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13104358/
我是一名优秀的程序员,十分优秀!