Walter Bright wrote:
Following the safe D discussions, I've had a bit of a change of mind. Time for a new strawman.

Based on Andrei's and Cardelli's ideas, I propose that Safe D be defined as the subset of D that guarantees no undefined behavior. Implementation defined behavior (such as varying pointer sizes) is still allowed.

Memory safety is a subset of this. Undefined behavior nicely covers things like casting away const and shared.

Safety has a lot in common with function purity, which is set by an attribute and verified by the compiler. Purity is a subset of safety.

Safety seems more and more to be a characteristic of a function, rather than a module or command line switch. To that end, I propose two new attributes:

@safe
@trusted

A function marked as @safe cannot use any construct that could result in undefined behavior. An @safe function can only call other @safe functions or @trusted functions.

A function marked as @trusted is assumed to be safe by the compiler, but is not checked. It can call any function.


Functions not marked as @safe or @trusted can call any function.

To mark an entire module as safe, add the line:

   @safe:

after the module statement. Ditto for marking the whole module as @trusted. An entire application can be checked for safety by making main() safe:

    @safe int main() { ... }

This proposal eliminates the need for command line switches, and versioning based on safety.

I think it's important to also have @unsafe. These are functions which are unsafe, and not trusted. Like free(), for example. They're usually easy to identify, and should be small in number.
They should only be callable from @trusted functions.
That's different from unmarked functions, which generally just haven't been checked for safety. I want to able to find the cases where I'm calling those guys, without having to mark every function in the program with an @safe attribute.

Reply via email to