EnsuringCodeCorrectnessinDProgramming
立即解锁
发布时间: 2025-08-20 02:27:28 订阅数: 3 


D语言实战指南:从入门到精通
# Ensuring Code Correctness in D Programming
## 1. Preventing Memory Corruption Bugs with @safe
Memory corruption bugs are extremely frustrating for programmers. They occur when you write to memory that you thought was owned by one object, but it ends up affecting another object unpredictably, often leading to crashes.
### 1.1 How to Use @safe
To prevent memory corruption bugs using the `@safe` annotation, follow these steps:
1. Mark as many functions as possible with the `@safe` annotation and attempt to compile. The compiler will indicate which functions fail the test.
2. Whenever possible, use high - level constructs like `foreach`, references, and D array slices instead of low - level features such as pointers.
3. Replace pointer arithmetic with array slicing. For example, replace `ptr++;` with `slice = slice[1 .. $];`.
4. Avoid using the `cast` operator.
5. Delegates used as arguments in `@safe` functions must also be marked `@safe`.
6. If a function needs to perform prohibited actions but can be manually verified as correct, mark it as `@trusted`.
7. Rely on the garbage collector. Manual memory freeing is hard to verify, and freeing memory while there are still references to it can cause memory corruption. So, unless all references are carefully encapsulated, they should not be marked `@trusted`. The garbage collector will never free a reference prematurely.
8. To disable `@safe`, mark functions as `@system`. These attributes work at the function level, so you may need to refactor code into additional functions to achieve the desired granularity.
You can also add `@safe:` at the top of your module and aggregate definitions to apply the annotation to all subsequent functions, instead of marking each function individually.
### 1.2 How @safe Works
The `@safe` annotation (formerly known as SafeD) is a set of optional restrictions that aim to make D code free of undefined behavior and memory - safe, ensuring that memory is never unexpectedly corrupted. It prohibits the use of several lower - level features in D:
| Prohibited Feature | Reason |
| --- | --- |
| Pointer manipulation | A pointer mistake is the most likely cause of memory corruption |
| Inline assembly | The compiler cannot guarantee its correct use |
| Casting between pointer types and using unions with pointers | Type safety is lost |
| Calling functions not marked `@safe` or `@trusted` | The compiler cannot verify their correct implementation |
| Taking the address of a local variable | Returning the address of a local can lead to stack corruption |
| Catching any exception not derived from `Exception` | The `Throwable` tree derived from `Error` signifies unrecoverable errors |
| Accessing globally shared data | A race condition between threads may cause undefined behavior |
| Explicitly casting between immutability or shared | This can break type system guarantees and violate thread safety |
However, `@safe` does not prevent null pointer dereferences. Since a null pointer terminates the program (through a segmentation fault or an unrecoverable error), no memory corruption occurs. It is recommended to use early - and - often assertions and/or `NotNull` types to aid in debugging null reference issues.
### 1.3 @trusted and @system
The `@trusted` functions violate one of the `@safe` rules but are manually verified to be correct. For example, pointer arithmetic is memory - safe if kept within bounds. If you can manually verify this, mark the function `@trusted`. A `@trusted` function should return a strongly - typed D slice and be as small and simple as possible.
Array bound checks can be turned off with the `–noboundscheck` flag to `dmd`, but only in non - `@safe` functions. In `@safe` functions, array bound checks are always present.
Marking too many functions `@trusted` is a mistake. It's better to rewrite functions to use higher - level features.
The `@system` functions have no restrictions. It is the default safety level due to D's heritage from C. To ensure your entire program is memory - safe, you can mark `main` as `@safe`, but this may limit your use of libraries.
```mermaid
graph TD;
A[Function] -->|Mark @safe| B{Compiler Check};
B -->|Pass| C[Safe Function];
B -->|Fail| D[Modify Function];
D -->|Mark @trusted| E[Trusted Function];
A -->|Mark @system| F[System Function];
```
## 2. Leveraging const - correctness
D's `const` and `immutable` methods offer strong guarantees, but sometimes these guarantees can make them difficult to use.
### 2.1
0
0
复制全文
相关推荐







