铛说对无效约束函数的调用不是常量表达式

问题描述

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
}

这里是code一起玩。

那么这是一个clang漏洞,还是代码格式错误,是否拥有ub或其他内容?


编辑:我认为指出clang允许从其他函数调用f也是有意义的。仅当从非经典函数调用f时,才会给出错误:

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

demo

解决方法

这是一个Clang错误,在10版和11版之间以及上个月的fixed之间都引入了。 consteval在Clang中的实现大部分(但不是全部)是完整的,并且该错误是在其中一个补丁添加了更完整的consteval支持之后出现的。

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

,

我发现c++20 final draft是:

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函数的有效返回类型。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...