7

clang(trunk) 给出以下代码的错误:

consteval void f() {}

int main() 
{ 
    f();  // error: call to consteval function 'f' is not a constant expression
          // note: subobject of type 'void' is not initialized
}

而 gcc(trunk) 编译它没有错误。

我觉得这可能是一个 clang 错误,因为 gcc 和 clang 都接受这个代码:

consteval int g() { return 42; }

int main() 
{ 
    g();  // ok
}

这是要玩的代码。

那么这是一个clang错误,还是代码格式错误,或者有ub,或者其他什么?


编辑:我觉得有必要指出 clang 允许f从其他函数调用,如果它们也是 consteval 的话。它仅在f从非 consteval 函数调用时给出错误:

consteval int h() 
{ 
    f();       // ok
    return 42; 
}

演示

4

2 回答 2

6

这是在版本 10 和版本 11 之间引入的 Clang 错误,并在上个月修复。Clang 中的实现consteval大部分但不完全是完整的,这个错误是在其中一个补丁添加更完整的consteval支持之后出现的。

详细信息:Clang 常量评估器的顶级入口点检查结果是否是常量表达式的允许结果——它检查结果不包含指向自动存储持续时间或临时或类似的指针。但是此检查从未更新以适应void文字类型,并且会拒绝void“未初始化”的类型值。在添加支持之前从未注意到这一点consteval,因为所有顶级常量评估都是非void类型的。

于 2020-09-21T01:09:38.250 回答
0

我发现c++20 最终草案是:

9.2.5 constexpr 和 constevals 修饰符[dcl.constexpr] (2) 在函数声明中使用的 constexpr 或 consteval 说明符将函数声明为 constexpr 函数。使用 consteval 说明符声明的函数或构造函数称为动画函数。析构函数、分配函数或释放函数不应使用 consteval 说明符声明。

(3) constexpr 函数的定义应满足以下要求:

3.1 其返回类型(如果有)应为文字类型;

6.8 类型 [basic.types]

(10) 一个类型是文字类型,如果它是:

(10.1) 简历无效

...

因为这voidconsteval函数的有效返回类型。

于 2020-08-11T20:18:44.417 回答