Initializing an Immutable Field with Magic: The "Fake Placement New" Technique

FeepingCreature feepingcreature at gmail.com
Fri Jul 26 12:36:26 UTC 2019


On Friday, 26 July 2019 at 12:12:19 UTC, ag0aep6g wrote:
> As far as I know, we usually say that this function:
>
>     void f(immutable int* p)
>     {
>         /* ... do something with *p ... */
>         g();
>         /* ... do more stuff with *p ... */
>     }
>
> can assume that `*p` is the same before and after calling `g`. 
> But if unions have the power to defeat immutable, that 
> assumption is invalid.

This is not correct, though it seems correct. This example hits 
the key of the problem though, so well spotted.

What if `g()` manually freed `p`, then allocated some new memory, 
and that new memory just so happened to exist at the same 
address? You would have observed a change in the value of `p`, 
even though it was marked immutable.

Now, this is invalid behavior, but it's not invalid behavior *of 
f*; the entire program is just written in a way that you were 
able to keep one pointer alive past the lifespan of the data it 
referenced.

Nullable and Algebraic, two types that run into such issues 
(Nullable uses the union hack internally!) let you control the 
lifespan of its members via `nullify` or assigning a different 
type, respectively. As such, if you take a reference to 
Nullable.get or an algebraic member, and then nullify or reassign 
it, you have broken your program. It is up to the user, not the 
compiler, to ensure that this does not happen.



More information about the Digitalmars-d mailing list