D not considered memory safe
Steven Schveighoffer
schveiguy at gmail.com
Sat Jul 13 20:37:35 UTC 2024
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](https://github.com/mysql-d/mysql-native/blob/57fbc2b61aa93dccc11b2f45d3ae23552fd1fdff/source/mysql/impl/connection.d#L32). 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
More information about the Digitalmars-d
mailing list