为什么未初始化的constexpr变量不是常量

why is an uninitialized constexpr variable not constant?

本文关键字:常量 变量 constexpr 初始化 为什么      更新时间:2023-10-16

我不确定这是编译器错误还是误解了constexpr:

struct S{};
constexpr S s1{};
constexpr S s2;
struct test{
    static constexpr auto t1 = s1;
    static constexpr auto t2 = s2;  //error here
};

GCC 4.8给了我一个奇怪的错误"错误:字段初始值设定项不是常量"。s2真的不是常数吗?如果是,为什么?

为了清楚起见,我实际上在代码中使用了一堆空结构(用于元编程https://github.com/porkybrain/Kvasir)所以我对这个具体的例子很感兴趣。

更新:代码应该编译,因为[class.ctor]/5读取:

隐式定义的默认构造函数执行类的初始化集,该初始化集将由用户为该类编写的默认构造函数来执行,该类没有ctor初始值设定项(12.6.2)和空的复合语句。如果用户编写的默认构造函数满足constexpr构造函数(7.1.5)的要求,那么隐式定义的默认构造函数就是constexpr

由于S只是一个空结构,因此隐式定义的默认构造函数是空的,因此满足constexpr的要求。

所以在这里,您要处理的是编译器的不完美,您必须以某种方式解决这个问题。


老答案:

Clang发出更合理的错误信息:

main.cpp:3:13: error: default initialization of an object of const type 'const S' 
requires a user-provided default constructor
constexpr S s2;
            ^

[dcl.constexpr]/9提供了解释,甚至几乎完全是您的代码示例:

对象声明中使用的constexpr说明符将对象声明为常量。此类对象应具有文字类型,并且应进行初始化。(…)示例:

struct pixel {
    int x, y;
};
constexpr pixel ur = { 1294, 1024 };// OK
constexpr pixel origin; // error: initializer missing

-结束示例]