c++ - 为什么保守函数允许未定义的行为?

标签 c++ undefined-behavior c++20 consteval

C++ 中的常量表达式有一个非常简洁的属性:它们的求值不能有未定义的行为 ( 7.7.4.7 ):

An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine ([intro.execution]), would evaluate one of the following:

  • ...

  • an operation that would have undefined behavior as specified in [intro] through [cpp] of this document [ Note: including, for example, signed integer overflow ([expr.prop]), certain pointer arithmetic ([expr.add]), division by zero, or certain shift operations — end note ] ;

确实尝试将 13! 的值存储在 constexpr intyields a nice compile error :

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;
}

输出:

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.

(顺便说一句,为什么错误说“调用'f(3)'”,而它是对f(13)的调用?..)

然后,我从 x 中删除 constexpr,但将 f 设为 consteval。根据the docs :

consteval - specifies that a function is an immediate function, that is, every call to the function must produce a compile-time constant

我确实希望这样的程序会再次导致编译错误。但相反,the program compiles and runs with UB .

这是为什么?

UPD:评论者认为这是一个编译器错误。我举报了:https://bugs.llvm.org/show_bug.cgi?id=43714

最佳答案

这是一个编译器错误。或者,更准确地说,这是一个“未实现”的功能(请参阅 the comment in bugzilla ):

Yup - seems consteval isn't implemented yet, according to: https://clang.llvm.org/cxx_status.html

(the keyword's probably been added but not the actual implementation support)

关于c++ - 为什么保守函数允许未定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58454657/

相关文章:

C++ C4716 初学者错误。了解错误概念但不确定如何使程序运行

c++ - 三向比较运算符的顺序推导不一致

c++20 - 缺少 Apple Clang 13 C++20 模块支持

c++ - 将相同数据写入两个文件的有效方法

c++ - '%' 标记和 'else' 之前的预期主表达式没有之前的 'if'

c++ - cudaMallocPitch 和 cudaMemcpy2D

c++ - 具体类型的 unique_ptr

c++ - 这种类型的双关语定义明确吗?

c++ - C++ 中未初始化的变量行为

c++ - 为什么 require 子句中的否定表达式需要括号?