Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decomposing relocation constructor #36

Open
SebastienBini opened this issue Jun 15, 2023 · 1 comment
Open

Decomposing relocation constructor #36

SebastienBini opened this issue Jun 15, 2023 · 1 comment

Comments

@SebastienBini
Copy link
Owner

Now that we have decomposing functions, and that D2839R1 achieves its relocation constructor with authorizing reloc in ctor-initializer, I think we can do better than what we are currently proposing.

What if the relocation constructor could act as a decomposing function with regards to its source object?
Right before entering the ctor-initializer, the source is decomposed into individual objects for each direct base and non-static data member. They live for the duration of the ctor-initializer, and if they are not relocated, they are otherwise destroyed in reversed declaration order.

class T : public B
{
public:
  T(T reloc) : /* starts lifetime of "B", _d1, _d2 and _d3 */
    B{reloc B}, _d1{reloc _d1}, _d2{this->_d1}
    /* _d3 and _d2 are destroyed, in that order */
  {}

private:
  D1 _d1;
  D2 _d2;
  D3 _d3;
};

We could even go as far as allowing delegating constructors with this approach:

class T : public B
{
public:
  T(T src) : T(reloc src, std::lock_guard{some_mutex}) {}

private:
  T(T reloc, std::lock_guard<std::mutex>) : /* starts lifetime of "B", _d1, _d2 and _d3 */
     B{reloc B}, _d1{reloc _d1}, _d2{this->_d1}
    /* _d3 and _d2 are destroyed, in that order */
    {}

private:
  D1 _d1;
  D2 _d2;
  D3 _d3;
};

The relocation constructor as currently proposed can stay. I believe the delegating ctor case is a motivating example of why we need both. This decomposing relocation constructor would only be reserved if the source object is named reloc. This allows us to write a second relocation ctor (like the private ctor of T) which benefits from the decomposition trait.

In the example, we might infinitely call the relocation constructor when building the first parameter of the private constructor. I believe the compiler must now that there exists an elided version of that private ctor so that it needn't call the relocation ctor again until it blows up the stack :/ Hence reloc must appear in the declaration of that second ctor. This should be okay as we cannot take the address of a constructor. However it feels a bit off that the name of a parameter changes the ABI, so maybe we should allow, for relocation constructors only, reloc T as well as T reloc: T(reloc T, std::lock_guard<std::mutex>) : ....

And... what about decomposing relocation assignment operator? I think they should be allowed if decomposing relocation ctors are a thing. I have not much to say about them though, no particular issue comes to mind.

@SebastienBini SebastienBini changed the title Easier relocation constructor syntax Decomposing relocation constructor Jun 15, 2023
@SebastienBini
Copy link
Owner Author

This conflicts with the approach raised in issue #38
Delegating relocation constructors are not supported with issue #38

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant