This code compiles just fine
int[] foo() @safe
{
int[5] a;
return a[];
}
void main()
{}
It really shouldn't. What it's doing is _not_ memory safe. And while implementing issue# 7087 would fix this particular case, it doesn't fix the problem in general, because all it takes is adding another function to the mix, and the compiler can't catch it:
int[] foo() @safe
{
int[5] a;
return bar(a);
}
int[] bar(int[] a) @safe
{
return a;
}
void main()
{}
Taking the slice of a static array is really no different from taking the address of a local variable, and that's already @system, so slicing a static array should be as well.
Honestly, I wish that static arrays didn't implicitly slice when being passed to functions taking dynamic arrays precisely because of how dangerous it is, and the fact that the implicit conversion makes it really easy to miss, but at least if it were marked @system, then it couldn't happen in @safe code, and it would be harder to have bugs like in the code above.
Comment #1 by bearophile_hugs — 2012-10-17T15:23:41Z
(In reply to comment #0)
> Taking the slice of a static array is really no different from taking the
> address of a local variable, and that's already @system, so slicing a static
> array should be as well.
This is a big change in D, so before going this route I suggest to think well about this topic.
Comment #2 by issues.dlang — 2012-10-17T16:35:57Z
> This is a big change in D, so before going this route I suggest to think well
about this topic.
The thing is that it _isn't_ memory safe. There's no question of that. So, per the definition of @safe, it has no business being @safe. It needs to be @system. If it's not, then SafeD is broken. I don't see how anyone could argue otherwise.
Yes, it's breaking change in the cases where people actually use @safe, but there's no way around that, and honestly, I suspect that most people don't mark their code @safe anyway, and it's only applicable to where static arrays are sliced, so I don't know how much code will really be broken. For folks who use static arrays and @safe heavily, it'll break a lot. For most other people, probably nothing.
Regardless, I don't see how we can _not_ make this change given what @safe is supposed to do.
Comment #3 by timon.gehr — 2012-10-17T16:42:44Z
(In reply to comment #2)
> > This is a big change in D, so before going this route I suggest to think well
> about this topic.
>
> The thing is that it _isn't_ memory safe. There's no question of that. So, per
> the definition of @safe, it has no business being @safe. It needs to be
> @system. If it's not, then SafeD is broken. I don't see how anyone could argue
> otherwise.
> ...
The code segment must be rejected, but what makes it unsafe is the escaping.
Banning the slicing is not very precise.
Comment #4 by bearophile_hugs — 2012-10-17T16:47:12Z
(In reply to comment #3)
> The code segment must be rejected, but what makes it unsafe is the escaping.
> Banning the slicing is not very precise.
Region analysis is not one of the design goals of D, unfortunately. But a little of such analysis will be useful in the D front-end.
Comment #5 by issues.dlang — 2012-10-17T16:57:55Z
> The code segment must be rejected, but what makes it unsafe is the escaping.
> Banning the slicing is not very precise.
It's exactly what happens with taking the address of a local variable. It's an error if the compiler can determine that it's escaping, but it's @system regardless. And because the compiler _can't_ guarantee that the reference isn't escaping, it really has no choice but to make it @system to take the address or slice in the first place. Doing otherwise would mean that it's possible to have memory corruption issues when only using @safe code, which would be violating @safe.
Comment #6 by yebblies — 2012-12-26T07:24:46Z
*** Issue 6844 has been marked as a duplicate of this issue. ***
Comment #7 by yebblies — 2013-07-27T23:41:54Z
*** Issue 7087 has been marked as a duplicate of this issue. ***
Comment #8 by yebblies — 2013-11-24T02:41:27Z
This is not very easy, because the compiler lowers all static array assignment to slice assignment, making _every_ static array assignment unsafe. That needs to be fixed first, and requires extensive changes in the interpreter.
Comment #9 by issues.dlang — 2013-11-24T14:21:13Z
> This is not very easy, because the compiler lowers all static array assignment
> to slice assignment, making _every_ static array assignment unsafe. That
> needs to be fixed first, and requires extensive changes in the interpreter.
Well, that's not good to hear, but unfortunately, I really don't think that the change is negotiable given what @safe is supposed to do and mean. So, even if it takes a while, it's something that needs to happen.
Comment #10 by bearophile_hugs — 2013-11-24T16:15:12Z
(In reply to comment #8)
> This is not very easy, because the compiler lowers all static array assignment
> to slice assignment, making _every_ static array assignment unsafe. That needs
> to be fixed first, and requires extensive changes in the interpreter.
Perhaps related, for optimization, and equally important:
https://d.puremagic.com/issues/show_bug.cgi?id=10305
Comment #11 by yebblies — 2013-11-24T17:18:07Z
(In reply to comment #10)
> (In reply to comment #8)
> > This is not very easy, because the compiler lowers all static array assignment
> > to slice assignment, making _every_ static array assignment unsafe. That needs
> > to be fixed first, and requires extensive changes in the interpreter.
>
> Perhaps related, for optimization, and equally important:
> https://d.puremagic.com/issues/show_bug.cgi?id=10305
No, not related. And not anywhere near as important.
Comment #12 by schveiguy — 2014-06-06T18:13:31Z
One thing to note here. A workaround is to use the temporary @trusted delegate to do the slicing.
Comment #13 by hsteoh — 2014-07-15T00:21:58Z
Hmm. Seems like if we implement 'scope' according to some combination of current proposals, we might be able to address this by having slices of static arrays return a scoped slice with lifetime not longer than the static array itself.
Comment #14 by schveiguy — 2014-11-03T16:22:35Z
(In reply to yebblies from comment #8)
> This is not very easy, because the compiler lowers all static array
> assignment to slice assignment, making _every_ static array assignment
> unsafe. That needs to be fixed first, and requires extensive changes in the
> interpreter.
Can you just ban slicing that escapes the statement?
Comment #15 by issues.dlang — 2016-04-16T04:34:45Z
Related: issue# 15932
Comment #16 by bugzilla — 2016-06-07T07:12:25Z
The first case no longer compiles, but the second case remains.