On Monday, 6 January 2014 at 20:35:39 UTC, bearophile wrote:
Currently this compiles because arr gets copied (or moved)
(another less visible write of arr happens at the point of its
initialization, it gets written by its init):
int[5] foo() pure {
int[5] arr;
return arr;
}
void main() {}
Currently even this function compiles, despite it's not
actually pure, because arr contains garbage (and it's garbage
that leaks information from other function stack frames, so
it's a security hazard), so in theory a good compiler should
disallow this:
int[5] foo() pure {
int[5] arr = void;
return arr;
}
void main() {}
On the other hand I think a strongly pure function like this
could be accepted, avoiding the final copy of the result (the
result contains a pointer to static data. Here the static data
is an array, but returning a pointer to a static struct is
equally valid):
int[] foo() pure {
pure static int[5] arr;
return arr;
}
void main() {}
"pure static" data means that 'arr' get cleaned (overwritten by
its init) at the entry of the function foo (just like for
not-static variables), to keep the function referentially
transparent.
So this is forbidden:
pure static int[5] arr = void;
A smart compiler can even see arr is fully assigned inside the
function and optimize away the first clear of the array:
int[] foo() pure {
pure static int[5] arr; // optimized as =void
foreach (immutable int i, ref r; arr)
r = i;
return arr;
}
void main() {}
Bye,
bearophile
Why not just return arr.dup instead? You're returning a slice of
a stack-allocated array, so of course you shouldn't write code
like this.