在 C++ 中减少 `constexpr` 对象生命周期合法吗?

Is reduction of `constexpr` object lifetime legal in C++?

对于普通对象(即使是 const 个),允许通过显式调用析构函数来结束它们的生命周期。稍后,例如,程序可以使用放置 new.

在同一内存位置开始另一个对象生命周期

但是调用constexpr对象的析构函数合法吗?它能产生一些有用的或至少是格式正确的程序吗?

很容易想象相反的情况:

struct A{
    int v = 0;
    constexpr void foo() { v ? throw 1 : ++v; }
    constexpr ~A() { foo(); }
};

constexpr A y;

int main() { y.~A(); y.~A(); }

这个(很可能是错误格式的)程序被所有编译器接受而没有任何警告:https://gcc.godbolt.org/z/aqMbfjxKT

在 Clang 中,它通过从 A.

constexpr 析构函数中抛出异常来完成

[dcl.constexpr] A constexpr specifier used in an object declaration declares the object as const.

你可以用这样的对象做任何你能用任何其他 const 对象做的事情。 constexpr,除了暗示声明对象的常量性之外,似乎不影响对象本身的任何内容。它只影响程序的静态属性,即哪些表达式是常量表达式,哪些模板实例化是有效的等。对于使用 constexpr 声明的对象的 运行 时间行为没有特殊规定说明符。

该标准多次使用类似于“constexpr 对象”的短语,但它似乎用词不当。在我看来,它应该引用 constexpr 变量。不应该有“constexpr 对象”这样的东西(就像没有内联对象),只有 constexpr 变量(就像有内联变量)。毕竟,constexpr 是一个 decl-specifier,就像 inline。这些变量所指的对象只是const.