digitalmars.D.learn - immutable promise broken in unions?
- Shriramana Sharma (21/21) Jan 02 2016 import std.stdio;
- John Colvin (12/32) Jan 02 2016 You are manually breaking immutable by making a union of
- Meta (3/13) Jan 02 2016 Surely the compiler should disallow this. It makes it trivial to
- Marc =?UTF-8?B?U2Now7x0eg==?= (3/18) Jan 02 2016 Right, this is a known bug:
- John Colvin (5/20) Jan 02 2016 Casting away immutable can sometimes be necessary (e.g. when
- Shriramana Sharma (5/9) Jan 02 2016 Yes it was in the context of talking to C that I needed to make such a
- tsbockman (2/6) Jan 02 2016 It should be disallowed in @safe code, though.
- Tobi G. (9/22) Jan 02 2016 The compiler doesn't protect you by carrying a bomb. :)
import std.stdio; union EarthLocation { struct { immutable double lon, lat, alt; } double[3] data; } void main() { EarthLocation d = {data: [4, 5, 6]}; writeln(d.data); d.data = [1, 2, 3]; writeln(d.data); } I get the output: [4, 5, 6] [1, 2, 3] I thought the promise of `immutable` was: never changes, whether via this interface or otherwise. How does then the above work? Using DMD 2.0.69.2 on Kubuntu 64 bit. --
Jan 02 2016
On Saturday, 2 January 2016 at 10:04:47 UTC, Shriramana Sharma wrote:import std.stdio; union EarthLocation { struct { immutable double lon, lat, alt; } double[3] data; } void main() { EarthLocation d = {data: [4, 5, 6]}; writeln(d.data); d.data = [1, 2, 3]; writeln(d.data); } I get the output: [4, 5, 6] [1, 2, 3] I thought the promise of `immutable` was: never changes, whether via this interface or otherwise. How does then the above work? Using DMD 2.0.69.2 on Kubuntu 64 bit.You are manually breaking immutable by making a union of immutable and mutable data and then writing to the mutable reference. This is roughly equivalent to casting away immutable and then writing to the reference. It's a bug in your code. All references to the same data should be 1) either immutable or const or all the references should be 2) either mutable or const (assuming the data was never immutable). Anything else is dangerous.
Jan 02 2016
On Saturday, 2 January 2016 at 12:07:31 UTC, John Colvin wrote:You are manually breaking immutable by making a union of immutable and mutable data and then writing to the mutable reference. This is roughly equivalent to casting away immutable and then writing to the reference. It's a bug in your code. All references to the same data should be 1) either immutable or const or all the references should be 2) either mutable or const (assuming the data was never immutable). Anything else is dangerous.Surely the compiler should disallow this. It makes it trivial to break the type system otherwise.
Jan 02 2016
On Saturday, 2 January 2016 at 12:08:48 UTC, Meta wrote:On Saturday, 2 January 2016 at 12:07:31 UTC, John Colvin wrote:Right, this is a known bug: https://issues.dlang.org/show_bug.cgi?id=13537You are manually breaking immutable by making a union of immutable and mutable data and then writing to the mutable reference. This is roughly equivalent to casting away immutable and then writing to the reference. It's a bug in your code. All references to the same data should be 1) either immutable or const or all the references should be 2) either mutable or const (assuming the data was never immutable). Anything else is dangerous.Surely the compiler should disallow this. It makes it trivial to break the type system otherwise.
Jan 02 2016
On Saturday, 2 January 2016 at 12:08:48 UTC, Meta wrote:On Saturday, 2 January 2016 at 12:07:31 UTC, John Colvin wrote:Casting away immutable can sometimes be necessary (e.g. when talking to other languages), so I'm not sure it should be disallowed, but it'd be great if it was somehow easier to catch these bugs.You are manually breaking immutable by making a union of immutable and mutable data and then writing to the mutable reference. This is roughly equivalent to casting away immutable and then writing to the reference. It's a bug in your code. All references to the same data should be 1) either immutable or const or all the references should be 2) either mutable or const (assuming the data was never immutable). Anything else is dangerous.Surely the compiler should disallow this. It makes it trivial to break the type system otherwise.
Jan 02 2016
John Colvin wrote:Casting away immutable can sometimes be necessary (e.g. when talking to other languages), so I'm not sure it should be disallowed, but it'd be great if it was somehow easier to catch these bugs.Yes it was in the context of talking to C that I needed to make such a union. But already making a union is breaking the type system in a way, no? --
Jan 02 2016
On Saturday, 2 January 2016 at 13:15:37 UTC, John Colvin wrote:Casting away immutable can sometimes be necessary (e.g. when talking to other languages), so I'm not sure it should be disallowed, but it'd be great if it was somehow easier to catch these bugs.It should be disallowed in safe code, though.
Jan 02 2016
On Saturday, 2 January 2016 at 10:04:47 UTC, Shriramana Sharma wrote:I thought the promise of `immutable` was: never changes.The compiler doesn't protect you by carrying a bomb. :) But there is another usecase where it makes sense to allow writing to other union members despite the overlap with immutable data:enum Types {Integer, Text, CalculationConstant} struct oldStyleLimitedBadVariant // Don't use that! D offers std.variant.Algebraic.. { Types type; union { int integer; string text; immutable float calculationConstant; } }There i would expect that i can write to integer and text at any time. togrue
Jan 02 2016