D not considered memory safe
Timon Gehr
timon.gehr at gmx.ch
Sat Jul 13 21:46:25 UTC 2024
On 7/13/24 21:27, Walter Bright wrote:
> On 7/13/2024 6:09 AM, Timon Gehr wrote:
>>> This to me is the most sensible way to go about it.
>>
>> It's not. You'll quickly lose track of the 3 kinds of `@trusted`
>> functions:
>>
>> - @trusted functions that should be @safe
>> - @trusted functions that should be @trusted
>> - @trusted functions that must be @system
>>
>> This is plain safewashing.
>
> Not if the @trusted functions have a safe interface (though the compiler
> cannot check the interface for safety, it is up to the programmer).
> ...
Well, your suggestion was to put @trusted _everywhere_, not only on
functions with a safe interface. As Dennis points out, it seems that is
exactly what happened in some instances.
Anyway, `@trusted` indicates that whoever put it there reviewed the
implementation for memory safety. This makes this approach impractical.
>
>> If you want incremental safety in the current language, you have to
>> start at the leaves, and put your TODO's in comments.
>
> In my efforts to make the front end @safe, that approach does not work.
> The problem is that the front end flow graph is cyclical. There aren't
> many leaves, and a lot of those leaves in the front end have been marked
> as @safe.
> ...
The solution is to remove the unsafe constructs and then mark everything
safe in one go. The compiler currently cannot assist with this very
well, but it is easy to do. It should just have a way to enable
non-transitive safety checks.
>
>> OpenD has an interesting approach towards default safety. They enabled
>> a large fraction of safety checks in functions without a safety
>> annotation. To disable them, explicit @system is required. This way
>> you get linting benefits even without already ensuring full memory
>> safety guarantees.
>
> It's an interesting approach, but certainly half-baked. How does one
> decide which safety checks are to be included?
> ...
In a data-driven way. They enabled the checks that do not cause too much
pain to users. OpenD is a big monorepository with DMD, LDC, and most of
the packages that people actually use, so breaking changes actually
require breakage to be fixed as well.
Anyway, non-transitive checks can be a useful tool for all function
attributes, and they have the benefit of not over-specifying their
guarantees. This can even be done with pragmas. I implemented a simple
pragma to (non-transitively) error out on implicit GC allocations, and
it was helpful for performance optimization.
>
>> Anyway, there are many language-assisted ways to make incremental
>> @safe migration work (some would require only minimal changes to the
>> compiler), but I think slapping @trusted everywhere will not do
>> anything to improve the perceptions about D's memory safety.
>
> You've often been quite adamant about memory safety being 100% (and I
> tend to appreciate that point of view and am in agreement with it).
Yes, @safe should mean memory safe. It should not mean: We'd like this
to be memory safe, but it is work in progress.
> A half-baked approach won't help, either.
> ...
Well, if the goal is incremental migration to `@safe`, a process of
enabling non-transitive safety checks on a function-by-function basis
and then later making it transitive is much more baked than random
application of @trusted, and it completely bypasses any issues with big
cyclic call graphs.
> With the @trusted approach, I'll often change it to @safe, fix what I
> can, then put it back to @trusted.
The fake-`@trusted` approach is half-baked, error prone, and undercuts
@safe. The fully baked way is to provide actual tooling for the use case
of incremental migration to memory safety.
More information about the Digitalmars-d
mailing list