Memory Safety for a program is defined as it being impossible for the program to corrupt memory. Therefore, the safe subset of D consists only of programming language features that are guaranteed to never result in memory corruption. See this article for a rationale.
Memory-safe code cannot use certain language features, such as:
- Casts that break the type system.
- Modification of pointer values.
- Taking the address of a local variable or function parameter.
Memory safety can be enabled on a per-function basis using the @safe attribute. This can be inferred when the compiler has the function body available. The @trusted attribute can be used when a function has a safe interface, but uses unsafe code internally. These functions can be called from @safe code.
Array bounds checks are necessary to enforce memory safety, so these are enabled (by default) for @safe code even in -release mode.
Memory safety does not imply that code is portable, uses only sound programming practices, is free of byte order dependencies, or other bugs. It is focussed only on eliminating memory corruption possibilities.