Safely moving structs in D

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Jan 24 03:46:47 PST 2017


On Monday, January 23, 2017 22:26:58 bitwise via Digitalmars-d-learn wrote:
> Is it ok to memcpy/memmove a struct in D?
>
> Quote from here:
> https://dlang.org/spec/garbage.html
>
> "Do not have pointers in a struct instance that point back to the
> same instance. The trouble with this is if the instance gets
> moved in memory, the pointer will point back to where it came
> from, with likely disastrous results."
>
> This seems to suggests it's ok to move structs around in memory
> without calling their postblit...but if this is the case, why
> does postblit even exist, if it's not strictly guaranteed to be
> called after the struct has been blitted?

Moving structs is fine. The postblit constructor is for when they're copied.
A copy is unnecessary if the original isn't around anymore - e.g. passing an
rvalue to a function can move the value; it doesn't need to copy it. Even
passing an lvalue doesn't need to result in a copy if the lvalue is not
referenced at any point after that function call. However, if you're going
to end up with two distinct copies, then they need to actually be copies,
and a postblit constructor will be called.

Types that would need postblit constructors would include anything doing
reference counting as well as anything that needs to do a deep copy of
something on the heap (though such structs aren't a great idea, since
usually copying is assumed to be cheap, and having the postblit constructor
allocate on the heap isn't exactly cheap). In reality, I don't think that
many structs typically have postblit constructors, but there are definitely
use cases where they're needed.

The bit about structs not pointing to themselves is to make it legal to move
structs in cases where the compiler knows that only one copy is required,
whereas in C++, because pointing to yourself is perfectly legal, the
compiler has to do a lot more copying, and they had to introduce move
constructors to get around the problem.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list