cannot modify struct with immutable members

ted via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jan 2 21:26:58 PST 2015


ketmar via Digitalmars-d-learn wrote:

> On Sat, 03 Jan 2015 14:45:24 +1030
> ted via Digitalmars-d-learn <digitalmars-d-learn at puremagic.com> wrote:
> 
>> Well, I just cleared up some of my misunderstanding.
>> 
>> I did not realise the mA (within struct Test) would be a _copy_ of arg,
>> not a reference (pointer) to arg.
>> 
>> So the more correct code snippet would be:
>> 
>> struct A
>> {
>>     int someInt;
>> }
>> 
>> struct Test
>> {
>>     @property { const(A) getA() { return *mA; } }
>>     this( in A arg )
>>     {
>>         mA = &arg;
>>     }
>> 
>> private:
>>     const A* mA;
>> }
>> 
>> void main()
>> {
>>     Test myTest1;
>>     A topA;
>> 
>>     topA.someInt = 100;
>> 
>>     void _someFunc( in A myA )
>>     {
>>         myTest1 = Test(myA);
>>     }
>> 
>>     Test myTest2 = Test(topA);      // is ok as expected
>>     _someFunc( topA );
>> 
>> 
>> }
> nonononono! ;-)
> please, don't use pointers like this. try to avoid pointers altogether,
> they are VERY dangerous. as for your sample: it is already invalid. see:
> 
>   this (in A arg) { mA = &arg; }
> 
> you are storing the address of *local* *var* *from* *stack* here. then
> local will go out of scope and... BANG! everyone is dead.

Oops...true (*blush*) - should have noticed this.

> 
>> This code snippet is me trying to understand whether I have a
>> fundamental misunderstanding with const, or whether it is an issue with
>> the compiler
> seems that you didn't get D `const`. it's deffers from C/C++ `const`.
> in most cases you don't need to use it at all. the funny thing of D
> const is that const "variable" cannot be changed in any way after
> assigning. that's why compiler complains: you're trying to change
> variable with `const` part, which is forbidden.
> 
> structure instance with const fields can be initialized only once, upon
> creation. so did `Test myTest1;` -- you initialized `myTest1` with
> default values. you can't reinitialize it later.
> 
> in C++ constness on member doesn't impose such restrictions. this is
> confusing for newcomers with C/C++ expirience. the best advice here is
> "don't use `const` in D unless you are fully understand what you are
> doing and how it work in D".

Ironically, I'm trying to use const in an effort to understand it...but 
there seems to be an unusual amount of pain until I grok it.

> 
>> I'm happy I've got a workaround (which seems to safely preserve the
>> const'dness), but I still don't understand why the compiler barfs on the
>> struct version as it should be 'replacing' the higher scoped
>> variable....
> you don't need `const` here at all. as far as i can see you want to
> tell the compiler that `mA` must not be changed after creating a
> struct. to achieve that you'd better move your struct to separate
> module and provide read-only getter.
> 
> you need to move your struct to separate module 'cause `private`
> modifier will not affect the code in the same module. one of the D
> rules is that the code in one module can access anything that was
> declared in the same module, including "private" members of
> structs/classes. C++ tries to achieve that with "friend" members, but
> as D has full-fledged module system, it doesn't need such tricks.
> 
> tl;dr: don't use `const` here, provide an accessor and stop
> worrying/helping the compiler. ;-)

Yeah.....its one of those cases where the prototype code is getting too 
ugly, and a refactorisation is required.....but no time !!

many thanks,
ted




More information about the Digitalmars-d-learn mailing list