Mik*_*ail 16 c++ undefined-behavior c++20 consteval
C ++中的常量表达式具有非常整洁的特性:它们的求值不能具有未定义的行为(7.7.4.7):
表达式e是核心常量表达式,除非按照抽象机([intro.execution])的规则对e求值,将求出以下值之一:
...
一种操作,其操作将具有本文档的[引言] [cpp]中指定的不确定的行为[注意:例如,包括带符号整数溢出([expr.prop]),某些指针算术([expr.add],除以零或某些移位操作-尾注];
尝试将13!
in 的值存储在constexpr int
确实产生一个不错的编译错误:
constexpr int f(int n)
{
int r = n--;
for (; n > 1; --n) r *= n;
return r;
}
int main()
{
constexpr int x = f(13);
return x;
}
Run Code Online (Sandbox Code Playgroud)
输出:
9:19: error: constexpr variable 'x' must be initialized by a constant expression
constexpr int x = f(13);
^ ~~~~~
4:26: note: value 3113510400 is outside the range of representable values of type 'int'
for (; n > 1; --n) r *= n;
^
9:23: note: in call to 'f(3)'
constexpr int x = f(13);
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
(顺便说一句,为什么错误是“调用'f(3)'”,而它却是对f(13)的调用?。)
然后,我constexpr
从中删除x
,但制作f
了一个consteval
。根据文档:
consteval-指定一个函数为立即函数,也就是说,对该函数的每次调用都必须产生一个编译时常量
我确实希望这样的程序会再次导致编译错误。但是,该程序可以使用UB编译并运行。
这是为什么?
UPD:评论者建议这是一个编译器错误。我报告了它:https : //bugs.llvm.org/show_bug.cgi?id=43714
这是一个编译器错误。或者,更准确地说,这是一个“未实现”的功能(请参阅bugzilla 中的评论):
是的 - 似乎 consteval 尚未实现,根据: https: //clang.llvm.org/cxx_status.html
(可能添加了关键字,但没有实际的实现支持)