https://issues.dlang.org/show_bug.cgi?id=19763
ag0aep6g <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #1 from ag0aep6g <[email protected]> --- (In reply to Jacob Carlborg from comment #0) > The following example fails to compile: > > struct Foo > { > const(char)* filename; > this(const(char)*) pure { } > } > > void main() > { > immutable a = Foo(null); > } > > Error: I think it's correct that this is rejected. The compiler could maybe realize that `null` poses no threat, or that the constructor doesn't actually set `filename`, but it's obviously not that smart. Generally, code like this must be rejected, because `main` still has access to the pointer that's passed to the constructor: ---- struct Foo { const(char)* filename; this(const(char)* f) pure { filename = f; } } void main() { char* p = new char; immutable a = Foo(p); *p = '!'; /* would mutate a.filename which is supposed to be immutable */ } ---- > But this code compiles: > > struct Foo > { > const(char)* filename; > this(const(char)*) pure { } > } > > Foo newFoo() pure > { > return Foo(null); > } > > void main() > { > immutable a = newFoo(); > } This is ok, because newFoo is `pure` and it immediately returns the constructed Foo. So it's guaranteed that the only mutable reference to the data ceases to exist right as the immutable one is created. > Also if "const(char)* filename" is changed to "char* filename" the first > example compiles. The constructor cannot possibly use the const(char)* parameter to set the char* field. So there is no way that the constructed Foo can refer to mutable data. If you make the parameter mutable, too, then the code will be rejected again. As far as I can tell, there's no bug here. --
