10

在下面的代码struct A中具有立即函数默认构造函数,并且在动态内存中创建结构的对象是指new A{}

struct A {       
    consteval A() {}
};

int main() {
    new A{};
}

只有 Clang 接受它。

海合会抱怨

error: the value of '<anonymous>' is not usable in a constant expression
    6 |     new A{};
      |           ^
note: '<anonymous>' was not declared 'constexpr'

MSVC 也是如此:

error C7595: 'A::A': call to immediate function is not a constant expression

演示:https ://gcc.godbolt.org/z/6Px5WYGzd

哪个编译器在这里?

4

1 回答 1

7

哪个编译器在这里?

调用consteval构造函数的格式new不正确。
MSVC 和 GCC 拒绝它是正确的;clang 是错误的,因为需要进行诊断。


struct A { consteval A() {} };

consteval生成A::A()立即函数1

立即函数只能从2,3调用:

  • 另一个即时功能,或
  • 一个 consteval if 语句,或
  • 一个常量表达式4

new A{}以上都不是。


1) [dcl.constexpr]/2

函数声明中使用的constexprorconsteval说明符将该函数声明为 constexpr 函数。使用说明符声明的函数或构造函数consteval称为立即函数

2) [expr.prim.id.general]/4

表示立即函数的潜在求值的 id 表达式应仅出现
(4.1) 作为立即调用的子表达式,或
(4.2) 出现在立即函数上下文中。

3) [expr.const]/13

如果表达式或转换可能被求值并且以下两种情况之一,则表达式或转换位于立即函数上下文中:
(13.1) 其最内层的封闭非块范围是立即函数的函数参数范围,或
(13.2) 其封闭语句是封闭的 ([stmt .pre]) 由 consteval if 语句 ([stmt.if]) 的复合语句。

如果表达式或转换是立即函数的潜在评估显式或隐式调用并且不在立即函数上下文中,则它是立即调用。
立即调用应为常量表达式。

4) [expr.const]/11.2

一个常量表达式要么是一个泛左值核心常量表达式,它引用一个作为常量表达式(如下定义)的允许结果的实体,要么是一个纯右值核心常量表达式,其值满足以下约束:
(11.2) 如果值是指针类型的,它包含具有静态存储持续时间的对象的地址,超过此类对象末尾的地址([expr.add]),非立即函数的地址,或空指针值,

于 2022-01-17T16:03:04.557 回答