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