cannot modify struct with immutable members

ketmar via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jan 2 21:07:02 PST 2015


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.

> 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".

> 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. ;-)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: not available
URL: <http://lists.puremagic.com/pipermail/digitalmars-d-learn/attachments/20150103/77a52be0/attachment.sig>


More information about the Digitalmars-d-learn mailing list