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

FeepingCreature feepingcreature at gmail.com
Fri Jul 26 11:14:02 UTC 2019


On Friday, 26 July 2019 at 10:53:32 UTC, ag0aep6g wrote:
> My point is that you can't do either. You can't mutate 
> immutable data. Doesn't matter whether you try it with a `cast` 
> or with `__ctor`. Both ways are not allowed.

Sure you can. Look at the link, you're doing it :)

More specific, immutable is kind of awkward. You have to 
differentiate between immutable types and immutable memory. Those 
are *often* the same, but not always.

The thing you cannot do is mutate memory that was *allocated* 
immutable - ie. that came out of new T or T() where T was marked 
immutable, or had immutable fields. But that doesn't happen with 
immutable fields inside a union, because unions screen off all 
that stuff; they can't not, because immutable fields and mutable 
fields may freely overlap. So instead of forbidding 
mutable-immutable overlap in unions, the language basically just 
throws up its hands and goes "yeah, whatever."

So when you're switching a tagged union to an immutable member, 
you're not dealing with "immutable memory", you're, effectively, 
dealing with an uninitialized field. And you can always set an 
uninitialized field to a new value, whether it's immutable or 
not, because that's *how the constructor hack works in the first 
place*. If abusing a constructor like this was broken, the 
constructor would *itself* be broken.


More information about the Digitalmars-d mailing list