C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Relocation in C++

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Tue, 16 Aug 2022 23:17:29 +0100
On Tue, 16 Aug 2022 at 18:51, Julien Villemure-Fréchette <
julien.villemure_at_[hidden]> wrote:

> > Generally speaking, a try-with-init ctor sounds dangerous. What happens
> if a subobject ctor throws, and the catch block absorbs the exception (e.g.
> does not call `throw` to propagate it). This means you would end up with a
> semi-constructed object, with some of its subobjects left uninitialized?
> It's even more hazardous if the constructor is a relocation constructor as
> some of the source subobjects will not be destructed.
> The exception must be propagated somehow, the caller must know that its
> object was not properly constructed.
>
> That can never happen: a constructor catch block cannot return normally
> (it has an implicit rethrow); and only the constructed member subobjects
> are automatically destroyed before entry to ctor catch block (hence you
> shouldn't access any non-static data members from the catch block).
> Furthermore, only if the exception was thrown from the body of a delegating
> ctor, then the dtor of this object is called before entry to the ctor catch
> block (hence you can't refer to 'this' from within the catch block).
>

Correct.


> > The issue is finding a way to add the initialization into the; the
> position between the `try` and `{` of a function-try-block is currently
> free real estate.
>
> There is a builtin solutions for this:
> Compose your class with private inheritance and/or use base from member
> idiom:
>
> https://www.boost.org/doc/libs/1_80_0/libs/utility/doc/html/utility/utilities/base_from_member
> .
>
> Note: The implementation of allocator aware containers (STL containers, ex
> std::vector) make extensive use of composition inheritance as a strategy to
> ensure memory allocation/deallocation is done before/after the container
> elements are constructed/destroyed.
>

 That won't work; or it would be needlessly inefficient. Per above:

> The need here to invoke custom code is to safely relocate objects that
both directly own a resource (i.e. their destructor releases the resource)
and have data members with throwing relocate. The idea is that before
starting to relocate members you can create a guard object that will
release the resource if a data member relocator throws, to avoid a resource
leak.

So the guard object needs to exist only for the duration of the relocating
constructor. But it would be useful if it could also be referred to from
the catch block of the function try.

Received on 2022-08-16 22:17:41