On Thursday, 11 July 2024 at 16:26:59 UTC, Walter Bright wrote:
> On 7/9/2024 8:58 AM, Nick Treleaven wrote:
> Any pattern to subvert safe involves the @trusted
attribute (except for compiler bugs, which editions help to fix). @trusted
is an obvious flag in code review that memory-safety may be violated. Grepping for @trusted
is an easy way to narrow down places where memory-safety is violated.
Arguing that @trusted can be abused is a tiny problem compared to the far harder to detect abuse in @system by default code.
That's right. Converting an entire program to @safe can be done successfully by doing it incrementally, getting it to pass its test suite at each step. The way to do it incrementally is to start by labeling each function @trusted, then making them @safe one by one.
I've done this, it works.
And, as you observe, grepping for "@trusted" makes for a builtin-in TODO list!
This is not the right approach. You start with marking things @safe
that are leaves, and then move up. Leave things as @system
until you can mark them as @safe
.
And all templates should be unmarked.
Marking everything @trusted
at first is just going to end in disaster.
When I converted mysql-native to have a @safe
interface, I would start by marking the module @safe:
at the top, and see what breaks. Then I would mark code @system
that was not safe, and see if I could massage it into being @safe
. I never marked anything @trusted
unless I could prove that it had a safe interface.
In some cases, marking @safe:
at the top does work! But it needs to be a module with no templates in it. In many cases, after finding all the safety problems, I had to mark selective pieces as @safe
.
In my case, the largest problem with my code was using Variant
which cannot be safe. I sure as hell could not mark all of variant trusted, as it's in Phobos, and it's also not safe.
Another problem with marking @safe:
at the top, and bludgeoning your way through with @trusted
marks is that you will end up marking actual @system
code as @trusted
, when it doesn't need to be. You only need the edge of the safety barrier to be marked as trusted.
And finally, if you mark everything trusted, and then find out later "oh, this actually cannot be made safe", then all of a sudden you might have to mark it as system, and now it cascades to a bunch of other things that you thought were already marked safe, and now those have to be marked system, and so on. Worst case scenario, you have external code depending on the trustedness, and now you break other people's code!
My recommendation is to use @safe:
at the top to find where you need to address safety problems, and then handle one item at a time, marking @safe
, @trusted
or @system
as appropriate. Then remove the top line (if it's not all safe).
-Steve