This segfaults with v2.097.1:
```
extern(C) void free(void* p);
struct S
{
void* p;
this(int)
{
p = cast(void*) 0xdeadbeef;
throw new Exception("blub");
}
~this()
{
if (p)
free(p);
}
}
void regular()
{
try
{
auto s = S(0); // not destructed because not successfully constructed
}
catch (Exception) {}
}
void empl()
{
import core.lifetime;
try
{
S s = void;
emplace(&s, 0);
} // `s` is destructed but in no well-defined state - boom
catch (Exception) {}
}
void main()
{
regular();
empl();
}
```
The emplace family (incl. copyEmplace for throwing postblit/copy constructor) should take care of resetting the instance to `T.init` in case of a throw, so that (unavoidable) destruction is well-defined.
It should probably only do so if an Exception is thrown (as opposed to an Error), to avoid the overhead for `nothrow` constructors.
This was suggested here: https://github.com/dlang/druntime/pull/3483#discussion_r682629332
Comment #1 by kinke — 2021-08-04T20:45:10Z
Works since v2.096.
Comment #2 by kinke — 2021-08-04T20:45:55Z
Dammit, wrong tab. ;)
Comment #3 by stanislav.blinov — 2021-11-27T08:36:52Z
I think the language should specify (as in, explicitly state in the spec) the expected state of an object in case its ctor throws. IMO it should be the user's job to leave their objects in a destructible state.
Perhaps something like: "If a constructor throws an exception, the object MAY still be destructed. Therefore, constructors should always leave objects in a destructible state."
Pseudo-code for emplace is:
emplaceInitializer(ptr);
constructAt(ptr, args);
Thus it makes little sense to write the initializer again. User was given a piece of memory, it's theirs now to keep tidy. It follows then that it should be the user's responsibility to maintain exception safety in their ctors.
An outlier here is emplacement of arrays, where it does make sense to write .init into the remainder of array if an exception was thrown, as that *is* assumed to contain garbage state.
Overwriting partially-constructed state with .init can potentially be problematic sine can cause resource leaks.
Comment #4 by stanislav.blinov — 2021-11-27T08:38:07Z
*since it can. Typing before coffee...
Comment #5 by robert.schadek — 2024-12-07T13:41:16Z