You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> **Try it online:**[Interactive Playground](https://cs01.github.io/llvm-project/) - See null-safety warnings in real-time
4
6
5
7
Nullsafe C adds NULL checks to catch errors at compile-time. It is 100% compatible with existing C codebases and can be used incrementally to identify safety issues at compile-time.
6
8
7
9
This provides the following benefits:
8
-
* This makes the code safer by reducing the number of potential runtime null dereferences
9
-
* Improves developer experience by shifting errors left
10
-
* Makes the code more readable
11
-
* Adds type errors that other more modern languages have (Rust, TypeScript, Kotlin)
12
-
13
-
**Try it online:**[Interactive Playground](https://cs01.github.io/llvm-project/) - See null-safety warnings in real-time in your browser!
10
+
* Catches errors at compile-time rather than runtime, reducing crashes
11
+
* Improves developer experience by shifting errors left and showing issues in the IDE as you code
12
+
* Makes code more readable and maintainable, including annotations with `_Nonnull`
13
+
* Adds type checking that more modern languages have (Rust, TypeScript, Kotlin)
14
14
15
15
Nullsafe C treats all pointers as potentially null ('nullable') unless it is certain they are not. It does this in two ways.
16
16
@@ -20,14 +20,18 @@ The second is by using Clang's [`Nullability`](https://clang.llvm.org/docs/Attri
20
20
21
21
If using a compiler other than clang, you can add `#define _Nonnull` as a no-op. You will not get the same compile checks as with Nullsafe C (clang fork), but the compillation will still succeed without error.
22
22
23
+
When a function is called, it will reset any type refinements, assuming there may be side effects. If the variable is marked `const` in the function signature the type narrowing is maintained, because it is guaranteed to not be made null within the function.
24
+
25
+
Note that this does not change any of the generated code. There are no performance impacts, it strictly does compile-time checks.
26
+
23
27
## Examples
24
28
25
29
```c
26
30
voidunsafe(int *data) {
27
31
*data = 42; // warning: dereferencing nullable pointer of type 'int * _Nullable'
28
32
}
29
33
```
30
-
[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCB1bnNhZmUoaW50ICpkYXRhKSB7CiAgKmRhdGEgPSA0MjsgLy8gd2FybmluZzogZGVyZWZlcmVuY2luZyBudWxsYWJsZSBwb2ludGVyIG9mIHR5cGUgJ2ludCAqIF9OdWxsYWJsZScKfQ%3D%3D)
34
+
*[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCB1bnNhZmUoaW50ICpkYXRhKSB7CiAgKmRhdGEgPSA0MjsgLy8gd2FybmluZzogZGVyZWZlcmVuY2luZyBudWxsYWJsZSBwb2ludGVyIG9mIHR5cGUgJ2ludCAqIF9OdWxsYWJsZScKfQ%3D%3D)*
31
35
32
36
Type narrowing:
33
37
```c
@@ -37,15 +41,15 @@ void safe(int *data) {
37
41
}
38
42
}
39
43
```
40
-
[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlKGludCAqZGF0YSkgewogIGlmIChkYXRhKSB7CiAgICAqZGF0YSA9IDQyOyAvLyBPSyAtIGRhdGEgaXMgbm9uLW51bGwgaGVyZQogIH0KfQ%3D%3D)
44
+
*[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlKGludCAqZGF0YSkgewogIGlmIChkYXRhKSB7CiAgICAqZGF0YSA9IDQyOyAvLyBPSyAtIGRhdGEgaXMgbm9uLW51bGwgaGVyZQogIH0KfQ%3D%3D)*
41
45
42
46
Anontated with `_Nonnull`:
43
47
```c
44
48
voidsafe_typed(int *_Nonnull data) {
45
49
*data = 42; // OK - we know data is not null so we can derefernce it
46
50
}
47
51
```
48
-
[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlX3R5cGVkKGludCAqX05vbm51bGwgZGF0YSkgewogICpkYXRhID0gNDI7IC8vIE9LIC0gd2Uga25vdyBkYXRhIGlzIG5vdCBudWxsIHNvIHdlIGNhbiBkZXJlZmVybmNlIGl0Cn0%3D)
52
+
*[Try it in the interactive playground](https://cs01.github.io/llvm-project/?code=dm9pZCBzYWZlX3R5cGVkKGludCAqX05vbm51bGwgZGF0YSkgewogICpkYXRhID0gNDI7IC8vIE9LIC0gd2Uga25vdyBkYXRhIGlzIG5vdCBudWxsIHNvIHdlIGNhbiBkZXJlZmVybmNlIGl0Cn0%3D)*
49
53
50
54
51
55
## Installation
@@ -78,7 +82,7 @@ Each release includes:
78
82
79
83
Once installed, configure your editor to use the null-safe `clangd`. Install the `clangd` extension from llvm and set the path to the clangd binary you just downloaded.
80
84
81
-
**VSCode:**
85
+
**VS Code:**
82
86
```json
83
87
// settings.json
84
88
{
@@ -107,11 +111,11 @@ Do not that this is not a comprehensive solution, since Null pointer dereference
107
111
| Double-free | ❌ Unsafe | ❌ Unsafe |
108
112
| Uninitialized memory | ❌ Unsafe | ❌ Unsafe |
109
113
110
-
Although this doesn't fix all memory safety issues, it catches Null pointer dereferences for free.
114
+
Although this doesn't fix all memory safety issues, it catches Null pointer dereferences for free. For additional memory safety, consider a language other than C.
111
115
112
116
### Why you still might want to try this
113
117
114
-
While Null-Safe Clang doesn't solve all memory safety issues, null pointer dereferences are a significant problem:
118
+
While Null-Safe Clang doesn't solve all memory safety issues in C, null pointer dereferences are a significant problem:
115
119
116
120
- Many memory safety bugs involve null pointer dereferences
117
121
- Easier to adopt than rewriting in Rust (100% compatible with existing C code)
@@ -124,11 +128,11 @@ While Null-Safe Clang doesn't solve all memory safety issues, null pointer deref
0 commit comments