Should have been:
void sideeffect();

struct foo
{
    constexpr foo() { val = 0; }
    ~foo() { if (val) sideeffect(); }

    int val;
};

constinit foo f;

int bar = (f.val = 1, throw 0, 0);

pt., 17 lip 2020 o 00:16 Maciej Cencora <m.cencora@gmail.com> napisał(a):
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);


czw., 16 lip 2020 o 23:26 Thiago Macieira <thiago@macieira.org> napisał(a):
On Thursday, 16 July 2020 13:54:24 PDT Maciej Cencora wrote:
> As far as I understand the latest C++ draft, constexpr destructor doesn't
> make the type trivial. It is just that constexpr destructor is allowed to
> be called in constexpr context (while in previous C++ standards only types
> with trivial destructors were allowed in constexpr context).

Sorry, I misspoke. I didn't mean it was a trivial type. I meant it was a
*literal* type.

http://eel.is/c++draft/basic.types#10

Specifically, "a type is a literal type if ... it has a constexpr destructor"
Changed from C++17 that required trivial.

Literal types are required (but not sufficient condition) for constexpr
functions.

> So I guess this would fail to compile, because such a global would still
> require a runtime registration of the destructor during initialization.

I think it would succeed in compiling but, despite the constexpr destructor,
would always emit a dynamic initialiser to destroy this object dynamically. I
think it makes sense, as any non-trivial destructor is necessarily doing
something, so it must be run

I'd like a "don't destroy" marker to go along constinit.

--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel System Software Products