Ah, I see what you mean.
Since constinit forces constant initialization, the object is properly constructed before any dynamic initialization takes place, and any other globals can safely reference it during their dynamic initialization.
So you can register non-trivial destructor for const init variables before performing dynamic initialization of other globals or executing main.
And even in case dynamic initialization will be interrupted due to an exception, the destructor for such a const-init global will be called as expected.
This should work safely even across different translation units.
Constexpr destructor doesn't change anything in this case.
void sideeffect();
struct foo
{
constexpr foo() { val = 0; }
~foo() { if (val) sideeffect(); }
int val;
};
foo f;
int bar = (f.val = 1, throw 0, 0);