Best way to make a template function conditionally @trusted
tsbockman
thomas.bockman at gmail.com
Sat Apr 3 22:48:01 UTC 2021
On Friday, 2 April 2021 at 19:49:30 UTC, ikod wrote:
> On Thursday, 1 April 2021 at 22:35:01 UTC, tsbockman wrote:
>> Suppose I have a templated struct member function for which I
>> can compute at compile-time when the function is memory safe,
>> and when it is not. But, the compiler cannot correctly
>> determine this automatically.
>
> Compiler should be able to derive safety of templated
> functions. You may just omit `@safe`/`@trusted`.
The compiler's approach to verifying memory safety is very
simplistic: it declares a function non-`@safe` if any potentially
unsafe operation is found in its implementation, without regard
for the context. It can only ever infer `@safe` or `@system`,
never `@trusted`.
The reason `@trusted` is in the language at all is to allow the
programmer to manually mark as memory safe those functions which
contain operations that would be unsafe in some other context,
but which the programmer has manually analyzed and verified to be
incapable of violating memory safety, no matter what inputs it
receives.
Consider the following program:
```D
import std.stdio;
void writeSafe()(int[2] stuff ...) {
foreach(n; 0 .. stuff.length)
writeln(stuff[n]);
}
void writeTrusted()(int[2] stuff ...) {
foreach(n; 0 .. stuff.length)
writeln(stuff.ptr[n]);
}
void main() @safe {
writeSafe(3, 5);
writeTrusted(3, 5);
}
```
`writeSafe` and `writeTrusted` generate identical code, and are
equally memory safe in reality. The compiler even knows this on
some level, because it correctly deduces that the bounds check
for `stuff[n]` can never fail, and omits it even in `writeSafe`.
Nevertheless, because `.ptr` can be used to violate memory safety
in other contexts, `writeSafe` is inferred as `@safe`, while
`writeTrusted` is inferred as `@system`. And so, the program
above will not compile as it stands.
This is, of course, a trivial example where there is no benefit
to using the non-`@safe` version, but there are more complex
cases where the desired algorithm is memory safe as a whole, but
it cannot be expressed in D without using some operations that
are forbidden in `@safe` code.
More information about the Digitalmars-d-learn
mailing list