www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - emplace, immutable members and undefined behaviour

reply aewils <a b.cd> writes:
According to http://dlang.org/const3.html any modification of 
immutable data causes undefined behaviour. Now I want to 
initialise a struct with immutable members in some malloc'd 
memory and found the emplace function. I came up with the 
following code:

import core.stdc.stdlib;

import std.conv;

struct Point {
  immutable double x;
  immutable double y;
}

void main() {
  void* a = malloc(Point.sizeof);
  Point* p = cast(Point*) a;
  emplace!Point(p, 1.0, 2.0);
}

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?
Nov 15 2015
parent reply Tobias Pankrath <tobias pankrath.net> writes:
 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;
Nov 15 2015
parent reply Tobias Pankrath <tobias pankrath.net> writes:
On Sunday, 15 November 2015 at 10:59:43 UTC, Tobias Pankrath 
wrote:
 Point* p = (allocate memory from somewhere);
 emplace!Point(p, 1, 2);

 immutable(Point)* immutableP = cast(immutable(Point)*) p;
You could also use the emplace version that takes untyped memory:
Nov 15 2015
parent aewils <a b.cd> writes:
On Sunday, 15 November 2015 at 11:12:02 UTC, Tobias Pankrath 
wrote:
 On Sunday, 15 November 2015 at 10:59:43 UTC, Tobias Pankrath 
 wrote:
 Point* p = (allocate memory from somewhere);
 emplace!Point(p, 1, 2);

 immutable(Point)* immutableP = cast(immutable(Point)*) p;
You could also use the emplace version that takes untyped one.
Missed that one... Thanks!
Nov 15 2015