@trusted assumptions about @safe code
ag0aep6g
anonymous at example.com
Wed May 27 17:02:15 UTC 2020
On 27.05.20 18:04, Paul Backus wrote:
> On Wednesday, 27 May 2020 at 15:14:17 UTC, ag0aep6g wrote:
[...]
>> From your previous post I figured that this is your position towards
>> calling @safe from @trusted:
>>
>> @trusted code is not allowed to rely on the documented
>> return value of an @safe function. The @trusted function
>> must instead verify that the actually returned value is
>> safe to use.
>
> This is my position on *any* function calling *any other* function. Even
> in 100% @system code, I must (for example) check the return value of
> malloc if I want to rely on it not being null.
>
>> I'm not sure if I'm representing you correctly, but that position
>> makes sense to me. At the same time, it doesn't seem feasible, because
>> I don't see how we're going to get users to adhere to that.
>
> Why does it not seem feasible? Checking return values is defensive
> programming 101. People already do this sort of thing all the time.
I think we're on the same page for the most part, but not here.
I'm pretty sure that you agree with this: When we call C's strlen like
so: `strlen("foo\0".ptr)`, we can assume that the result will be 3,
because strlen is documented to behave that way.
I'm not sure where you stand on this: If an @safe function is documented
to return 42, can we rely on that in the same way we can rely on
strlen's documented behavior? Let's say that the author of the @safe is
as trustworthy as the C standard library.
If we can assume 42, a bug in @safe code can lead to memory corruption
by breaking an assumption that is in @trusted/@system code. Just like a
bug in @system code can have that same effect. This might be obviously
true to you. But I hadn't really made that connection until recently. So
if you agree with this, then I think we're on the same page now. And we
just accept that a mistake in @safe code can possibly kill safety.
On the other side, if we cannot assume that 42 being returned, but we
need to check that 42 was indeed returned, then the weird scenario
happens where an @safe `my_strlen` becomes more cumbersome to use than
C's @system `strlen`. I don't think any existing @trusted code was
written with that in mind.
If I'm not making any sense, maybe we can compare our answers to the
question whether the following snippets (copied from earlier) can really
be @trusted.
I think this one is fine:
----
void f() @trusted
{
import core.stdc.string: strlen;
import std.stdio: writeln;
char[5] buf = "foo\0\0";
char last_char = buf.ptr[strlen(buf.ptr) - 1];
writeln(last_char);
}
----
And I think this one is fine, too:
----
size_t my_strlen(ref char[5] buf) @safe
{
foreach (i; 0 .. buf.length) if (buf[i] == '\0') return i;
return buf.length;
}
void f() @trusted
{
import std.stdio: writeln;
char[5] buf = "foo\0\0";
char last_char = buf.ptr[my_strlen(buf) - 1];
writeln(last_char);
}
----
More information about the Digitalmars-d
mailing list