Memory Safety
32.1 @safe, @trusted, @system
The compiler verifies memory safety: no pointer arithmetic, unsafe casts, void* reinterpretation, __gshared access, or calls to @system code
The programmer guarantees safety. Callable from @safe. Keep it minimal and reviewed.
No checks (the default for non-template functions today) Templates and auto functions infer attributes. Mark public APIs @safe explicitly.
"Safe by default" is planned via editions. Write @safe code now.
@safe int[] firstN(int[] arr, size_t n) { return arr[0 .. n]; } // bounds-checked slicing
@trusted void zeroBuffer(ubyte[] buf)
{
import core.stdc.string : memset;
memset(buf.ptr, 0, buf.length); // unsafe call wrapped with a safe interface
}
@safe: // apply to the rest of the module32.2 DIP1000: Scope Pointers (-preview=dip1000)
DIP1000 enables @safe stack allocation, scope classes, and safe slicing of static arrays. It's on by default in newer compilers, so check your version's default.
@live (an experimental ownership/borrowing checker) is available for functions marked @live.
@safe int* escape()
{
int x;
return &x; // error with dip1000: reference to a local escapes
}
@safe void process(scope int[] data) { } // `data` can't escape (stored in a global or returned)
@safe ref int first(return ref int[2] arr) { return arr[0]; } // `return ref`: result tied to arr's lifetime
@safe int* ptr(return scope int* p) { return p; }32.3 Other Safety Features
Array bounds checking (-boundscheck=on|safeonly|off), null-dereference segfaults (no UB optimization in DMD), default initialization, no implicit narrowing, final switch, contracts, and immutable thread sharing.