Skip to content

Object slicing and relocation #23

Description

@SebastienBini

Consider the following scenario:

using reloc_only_t = gsl::non_null<std::unique_ptr<int>>;

struct B
{
  reloc_only_t _b;
};
struct D : B
{
  reloc_only_t _d;
};
// B and D are forcibly relocate-only

void sink(B);
void foo(D obj)
{
  sink(reloc obj); // What happens here?
}

Given the rules we established, I'd say this is ill-formed? I'm not sure of how object slicing happens behind the scene, but I guess it involves an extra copy of the base part of the object.

If we had move-only types instead, and had used std::move instead of reloc, the following would have happened in my understanding:

  • sink is called with an xvalue of D.
  • sink(B) is selected as we can move-construct B from a D xvalue.
  • B is constructed in sink's parameter slot, effectively leaving B's part of obj in a moved-from state, and not touching D's part.
  • At the end of foo (assuming obj is not an unowned parameter), its destructor is called.

In the general case (with relocate-only types or not), when reloc selects the relocation constructor, I would like to have a similar approach (assuming obj is not an unowned parameter):

  • sink is called with a prvalue of D.
  • sink(B) is selected as we can relocate-construct B from a D prvalue.
  • The non-B parts of obj are destructed.
  • B is constructed in sink's parameter slot, by relocating the B's part of obj.
  • obj lifetime ends before sink is called.

This would be equivalent to:

struct D : B
{
  reloc_only_t _d;
  B get_B(this D reloc) { return reloc B; } 
};
void foo(D obj)
{
  sink((reloc obj).get_B());
}

Except that it would happen automatically. I suspect it at least requires D to have no user-provided destructor.

What do you think?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions