C++ clang说对void consteval函数的调用不是一个常量表达式
clang(trunk)为以下代码提供了一个错误:C++ clang说对void consteval函数的调用不是一个常量表达式,c++,language-lawyer,c++20,constant-expression,consteval,C++,Language Lawyer,C++20,Constant Expression,Consteval,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)编译时没有错误 我觉得这可能是一个叮当作响的bug,因为g
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)编译时没有错误
我觉得这可能是一个叮当作响的bug,因为gcc和叮当都接受以下代码:
consteval int g() { return 42; }
int main()
{
g(); // ok
}
这是可以玩的游戏
那么这是一个叮当作响的bug,还是代码格式不正确,或者有ub,或者其他什么
编辑:我觉得有必要指出,如果其他函数也是consteval,那么clang允许从其他函数调用
f
。它仅在从非常量函数调用f
时给出错误:
consteval int h()
{
f(); // ok
return 42;
}
.我发现:
9.2.5 constexpr和constevals规范[dcl.constexpr]
(2) 函数声明中使用的constexpr或consteval说明符将该函数声明为constexpr函数。使用consteval说明符声明的函数或构造函数称为animediate函数。析构函数、分配函数或释放函数不得使用consteval说明符声明
(3) constexpr函数的定义应满足以下要求:
3.1其返回类型(如有)应为文字类型
及
6.8类型[基本类型]
(10) 如果类型是:
(10.1)cv无效
由于此
void
是consteval
函数的有效返回类型。这是一个在版本10和版本11之间以及上个月引入的异常错误。Clang中的consteval
的实现基本上是完整的,但不是完全完整的,在其中一个补丁添加了更完整的consteval
支持后,出现了此错误
详细信息:Clang常量计算器的顶级入口点检查结果是否为常量表达式的允许结果——它检查结果是否不包含指向自动存储持续时间或临时或类似值的指针。但该检查从未更新以适应
void
为文本类型的情况,并将拒绝void
为“未初始化”类型的值。在添加consteval
支持之前从未注意到这一点,因为所有顶级常量计算都是非void
类型。如果f是constexpr,它是否有效?(当强制使用constexpr时,比如constexpr int x=(f(),5);
)clang会这样做。@Dani不,它给出了相同的结果。@Barry True,但我觉得它已经在trunk中实现了一段时间了。那么这只是一个不完整的功能?不过还是一个奇怪的错误。那么我会说这是一个编译器错误。例如,其基本原理是std::sort
。“if any”包括构造函数和析构函数缺少返回类型<代码>void f()代码>没有返回类型。«cvvoid
»是一个“如果有的话”并不适合它。@language律师:谢谢你的解释。这使void成为conexpr/consteval函数的有效返回类型。@LanguageLawyer如何构造void
的对象?它从K&R那里得到了这个名字,因为它什么都不是。我想这就是clang的架构失败的原因。实际上,我并不怀疑f
的定义是正确的。问题是关于调用f()
,这就是错误的来源。注意,clang允许从其他consteval
函数调用f
。“if any”包含构造函数和析构函数没有返回类型实际上,只有构造函数没有返回类型,析构函数才不允许是consteval
。事实上,它现在可以编译。谢谢:)