[Issue 19183] DIP1000 defeated if auto used instead of scope in variable declaration with template this member function
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Aug 21 22:39:02 UTC 2018
https://issues.dlang.org/show_bug.cgi?id=19183
--- Comment #9 from ag0aep6g <ag0aep6g at gmail.com> ---
(In reply to Atila Neves from comment #8)
> > @safe code can mess with it
>
> No it can't, that's the point of @safe. Mess with it how?
@safe applies to functions/methods, not variables/fields. You can't forbid
@safe code from accessing a visible variable.
Example that's similar to your code:
----
int x = 41;
int y = 42;
struct S
{
int* p;
void t() @trusted
{
import core.stdc.stdlib: malloc;
if (p is null) p = cast(int*) malloc(2 * int.sizeof);
p[1] = 13;
}
void s() @safe { p = &x; }
}
void main() @safe
{
S s;
s.s();
s.t();
assert(y == 42); /* Fails. */
}
----
Here, `t` assumes that `p` will be the result of `malloc`. But there is no way
in the language to force @safe code to respect that assumption. You can always
add an @safe method like `s` that messes with `p`, and then `t` will violate
safety.
DIP 1000 doesn't help here. It doesn't add a mechanism with which we could make
`p` inaccessible from `s`.
We're drifting off-topic topic here, though. Maybe we should move it to the
forum if we're not on the same page by now?
[...]
> ----------
> @safe:
>
> const(int)* gInts;
>
> void main() {
> auto s = MyStruct();
> gInts = s.ptr;
> }
>
> struct MyStruct {
> int* ints;
> scope ptr(this This)() { return ints; }
> }
> ----------
You're still just copying an `int*` around, which isn't unsafe. `ptr` is
inferred as `return` so it's allowed to return `ints`. I suppose your point is
that `return` shouldn't be inferred? Maybe, but it's not obvious from the code.
A test case that shows actual damage (memory corruption) would go a long way.
[...]
> Because, from DIP1000:
>
> A variable is inferred to be scope if it is initialized with a value that
> has a non-∞ lifetime.
Without `scope` on the variable and without a destructor, there is no
indication that `s.ints` has a non-infinite lifetime.
> This very same code without a template this and instead manual
> instantiations of the three versions (mutable, const, immutable) doesn't
> compile _even_ if `auto` is used in the variable declaration.
I'm not sure if I understand that correctly, but this compiles just fine:
----
@safe:
const(int)* gInts;
void main() {
auto s = MyStruct();
gInts = s.ptr;
}
struct MyStruct {
int* _ints;
auto ptr() { return _ints; }
auto ptr() const { return _ints; }
auto ptr() immutable { return _ints; }
}
----
> Furthermore, if `auto` was enough to get away from compiler checks, DIP1000
> would be useless since nobody is going to remember to write `scope`.
Copying a pointer isn't unsafe. There's no reason for the compiler to reject it
unless you add further restrictions by using `scope`.
--
More information about the Digitalmars-d-bugs
mailing list