OK, this is not a corruption of @safe concept. The original code can be rewritten as follows:
int* ptr;
static void foo() @system {
ptr = cast(int*)1; // stomp memory
}
auto func(int n) @safe {
if (!ptr)
ptr = new int(n);
return &foo;
}
void main() { ... }
And func cannot assume the pointer value won't be corrupted, because someone can corrupt it.
But, in original code, the static variable `ptr` is declared inside the safe function. Therefore anyone cannot stomp it from outside of foo.
I think that everything inside @safe function should be safe or trusted. From the point of view, declaring @system function inside @safe is much dangerous. By disallowing it, we can stop writing error-prone code.
Comment #4 by code — 2014-06-05T14:03:15Z
(In reply to Kenji Hara from comment #3)
> I think that everything inside @safe function should be safe or trusted.
> From the point of view, declaring @system function inside @safe is much
> dangerous. By disallowing it, we can stop writing error-prone code.
I'm opposed to this change as it gratuitously increases language complexity. The current behavior is neither dangerous nor error prone. To see this, consider the following variation of your original example:
---
auto func() @safe {
static int* ptr;
if (!ptr)
ptr = new int;
*ptr = 42; // Write something to ptr.
return &ptr;
}
void main() {
auto pp = func();
func();
*pp = cast(int*)1;
func(); // crash!
}
---
Here, it is clear that it's not returning the pointer from func() that is unsafe, but writing a random value to it in main(). There is nothing that conceptually separates leaking a reference to a value out of a @safe function via a return value or a ref parameter from defining a nested function and passing that on.
To put it differently, what is dangerous in your examples is not what happens inside func(), but that you rely on manual, error-prone inspection of main() to evaluate correctness of the program.
Comment #5 by issues.dlang — 2014-06-05T19:38:16Z
Actually, I really don't see a problem here. The unsafe operation is in main. _That_ is where the @system function is called. Sure, the fact that func returns auto makes it harder to see, but if you marked main with @safe, then it would be clear, since the compiler would give then an error when fp was called.