On Friday, 1 November 2013 at 20:29:54 UTC, Jonathan M Davis wrote:
On Friday, November 01, 2013 14:28:55 Daniel Davidson wrote:
On Thursday, 31 October 2013 at 19:39:44 UTC, Jonathan M Davis

Deep copying is not the only reason to have a postblit. Smart pointers such as std.typecons.RefCounted require a postblit (or copy constructor if we had those) to do their job. Also, even if all you want is a deep copy, it's possible that the member being deep copied was allocated via something like malloc, in which case, the compiler couldn't take care of it for you.


So, deepCopy is a reason for postblit and I probably common for those not wanting shared state. You have mentioned two more uses for postblit, ref counting and dealing with something allocated with malloc. Honestly I am not sure the impact of the latter. Are you referring to `struct T { S *s }` where the s was allocated with malloc? I think you give up on const/immutable when ref counting anyway? Regardless, I imagine both of those cases are on the less common side and are probably not too troubled by const issues. I'm not suggesting getting rid of postblit. Neither am I against constructors. It just sounds like adding constructors is overkill if support for immutable language generated postblit were available. And I think it would be easy to add.

I'm just suggesting add an annotation that marks fields to be duped by a language generated postblit. The developer would not need to implement the postblit and it would be clear when/where sharing occurs. Then the language is still guaranteed immutable correct when using the language generated postblit.

I am now convinced avoiding `const(T) t` as a member is wise
advice. The suggestion of leaving it non-const and providing a
const accessor is good - but it won't prevent module code from
modifying it. I really want to make sure it is not being mutated.
So I'm now leaning toward this approach:

struct S {
const(T) *rc;
}

so I won't have the copy/postblit issues. Doesn't this bypass the
problems with `const(T) t`. The new risk is that somehow that
member variable is initialized with a stack variable.

If you do that, then rc can be mutated (and so the struct can be mutated), but what it points to can't be. So, from the sounds if it, it does what you want. Though honestly, I wouldn't worry about the rest of a module mutating your
member variable just because it has access to it.

Correct - I'm not worried about rc being modified as it is pretty easy to control that.

I was under the impression it is pretty easy to innocently/unknowingly mutate data. Suppose a member function passes that member `t` to any function in any other module. With slices and maps, what is really being passed around are pointers. Once you start passing them around in a non-const or non-immutable context you have objects sharing the same pieces data and eventually it could be changed, even though not in your module.

If you simply name member
variables differently than the public API (e.g _rc instead of rc) and then provide a const property to access the member, then the odds are very low that you're going to accidentally access the member directly. And if you can't keep track of what's in a single module well enough to avoid this sort of problem,
then your module is probably too big.

Not sure I agree because passing non-const instances to functions anywhere in the system is now allowed if the member is non-const. So it has less to do with the size of your module and more to do with where you are passing it. If you are passing it around non-const the door is wide open.

But if you're paranoid, you can
certainly add an extra layer indirection like you're suggesting. I wouldn't
bother though.

- Jonathan M Davis

Clearly I am paranoid :-)

But I think it is the case that const(T) and immutable(T) would be just fine and your reservations would be gone if the postblit were in fact immutable. If this were the case, wouldn't you change your stance and recommend const(T) or immutable(T) if in fact that is what the expectation is for the developer.

Thanks
Dan

Reply via email to