For ordinary objects (even for const
ones), it is permissible to end their lifetime by explicitly calling the destructor. Later, for example, the program can start another object lifetime in the same memory location using placement new
.
But is it legal to call the destructor of a constexpr
object? Can it result in some useful or at least well-formed program?
It is easy to imagine the opposite situation:
struct A{
int v = 0;
constexpr void foo() { v ? throw 1 : ++v; }
constexpr ~A() { foo(); }
};
constexpr A y;
int main() { y.~A(); y.~A(); }
This (most probably ill-formed) program is accepted by all compilers without any single warning: https://gcc.godbolt.org/z/aqMbfjxKT
And in Clang it finished by throwing an exception from constexpr
destructor of A
.
[dcl.constexpr] A
constexpr
specifier used in an object declaration declares the object as const.
You can do with such an object whatever you can do with any other const object. constexpr
, apart from implying constness of the declared object, doesn't seem to affect anything about the object itself. It only affects static properties of the program, that is, which expressions are constant expressions, which template instantiations are valid, etc. There are no special provisions for run-time behaviour of objects declared with the constexpr
specifier.
The Standard uses phrases similar to "constexpr object" a couple of times but it seems to be a misnomer. In my opinion it should have referred to constexpr variables instead. There should be no such thing as "constexpr objects" (like there are no inline objects), only constexpr variables (like there are inline variables). After all, constexpr
is a decl-specifier, like inline
. The objects that these variables refer to are just const.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With