this compiles and runs fine. Because emplace expects a typed
pointer, it actually modifies (*p).x and (*p).y
As far as I understand, this causes undefined behavior.
Are there any (safe) alternatives to this code other than
making the immutable members mutable?
As long as there are no other references to the immutable members
and you can guarantee that they are indeed in mutable memory
(both guaranteed by malloc) you are safe. If you really don't
want to write to any immutable member, you could do this:
struct Point {
double a;
double b;
}
Point* p = (allocate memory from somewhere);
emplace!Point(p, 1, 2);
immutable(Point)* immutableP = cast(immutable(Point)*) p;