Safe cast away from immutable
Jonathan M Davis via Digitalmars-d
digitalmars-d at puremagic.com
Mon Feb 8 12:43:23 PST 2016
On Monday, 8 February 2016 at 19:07:01 UTC, Iakh wrote:
> import std.stdio;
>
> struct S
> {
> void[] arr;
>
> auto f() pure @safe
> {
> int[] a = new int[4];
> arr = a;
> return a;
> }
> }
> void main() @safe
> {
> S s;
> immutable a = s.f();
> int[] b = (cast(int[])s.arr);
> writeln(a);
> b[0] = 1;
> writeln(a);
> }
>
> http://dpaste.dzfl.pl/13751913d2ff
The bug is that it's even legal to declare a as immutable. pure
functions that are strongly pure allow for the return value to
have its mutability altered, because it's guaranteed that what's
being returned isn't referenced anywhere else in the program.
However, f is not strongly pure. It's taking the this
pointer/reference as mutable, not immutable, which allows for the
memory that's allocated in it to escape - as you've done in this
example.
So, the compiler logic with regards to pure is buggy. Simply
having
struct S
{
void[] arr;
auto f() pure @safe
{
int[] a = new int[4];
arr = a;
return a;
}
}
void main() @safe
{
S s;
immutable a = s.f();
}
in a bug report should be sufficient to show the bug, even
without the rest of what you're doing.
In general, it should be impossible for member functions to be
considered strongly pure unless they're marked as immutable,
though the compiler could certainly be improved to determine that
no escaping of the return value or anything referencing it occurs
within the function and that thus it can get away with treating
the return value as if it's the only reference to that data, but
that would likely be farther into the realm of code flow analysis
than the compiler typically does.
Regardless, your example definitely shows a bug. Please report
it. Thanks.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list