const and immutable members

Daniel Davidson nospam at spam.com
Mon Sep 23 04:49:59 PDT 2013


On Monday, 23 September 2013 at 03:51:41 UTC, Jonathan M Davis 
wrote:
>> Doesn't using immutable there present the same problem as with
>> the slice? S is no longer assignable. But who would recommend 
>> not
>> using immutable in this case if you want aarr to be stable. If
>> you do not use immutable then who knows when your array will 
>> grow
>> without your expecting it? At least with the slice your memory
>> safety is in the control of your module if you make it private.
>> But with associative array it would depend entirely on client
>> code providing the data still having a handle on it.
>
> Of course, it's the same for AAs. Or classes. Or pointers. Or 
> int. Or float.
> It's the same for _any_ type. If you make any of them fully 
> immutable, then
> you can't reassign the struct, which makes the struct unusable 
> in a number of
> situations.
>
> But if your concern is client code messing with your member 
> variable, then
> don't give them access to it in the first place.

Not quite as much messing with the member as messing with what it 
points to. In the setup - rich data, read from the wire or disk, 
lots of nesting of lists, associative arrays, json like data, 
etc, the POD data is being read and stored into nested structs 
all prior to coming to my class. I want to ensure that the memory 
that I know both of us (S and the client code who built data to 
pass to S and other users) is not being modified.

I think of it like: int, double, char[10], immutable(T)[] (and 
string) are all similar in that there is no troublesome aliasing 
(even though there may be sharing). Associative array is 
different in that string[string] has troubling aliasing and your 
data can change from under you - unless you copy it deeply.

It seems the suggestion from above would be copy in postblits. 
But I don't think that scales from a nested class perspective. 
The problem is where and how to copy. Actually, that was the 
approach I was taking before, copying the data up front in 
postblits. In fact I created a generalized dup function that 
given type T will recursively copy all fields, giving care to 
deep copy those with potential for mutable aliasing. The general 
comments in one of the related threads then was it was silly to 
copy the data up front. Walter in fact said he would avoid all 
copying data on struct construction, preferring lazy copy on 
write semantics.

Walter's comment in this thread
http://forum.dlang.org/thread/k8ti2b$1iqj$1@digitalmars.com?page=7

      Have you ever written a struct that requires a deep copy?
      I have, and I always wound up redoing it so the deep copy 
was unnecessary.


I believe I asked how that would be done in the general sense but 
I don't think there were any good mechanisms. By, "in the general 
sense" I'm talking about dealing with composition at maybe 5 to 7 
layers and each struct containing types with mutable aliasing 
with lots of associative arrays.


> If you're making your member variables const or immutable so 
> that client code
> can't mutate them, then you're just causing yourself problems 
> because you
> didn't use proper encapsulation.

I'm now *considering* making them const because I don't want a 
large composition hierarchy of plain old data with postblits 
aggressively copying data unnecessarily before it gets finalized 
and passed to my struct S that is really only holding onto it as 
reference data/read only/forever immutable.



More information about the Digitalmars-d-learn mailing list