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
Copy file name to clipboardExpand all lines: _posts/2025-11-30-comptime-c-functions.md
+9-6Lines changed: 9 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,7 +18,10 @@ macro_version:
18
18
ret
19
19
```
20
20
21
-
Here is how it is achieved in C:
21
+
The best use-case I can think of for this technique is generating lookup tables at compile-time, since functions like `sin()`*also* successfully get optimized away. This technique seems to also work fine however for implementing runtime-allocated data structures, without needing macros.
22
+
23
+
# Required tricks
24
+
22
25
-`static inline` allows inlining across compilation boundaries.
23
26
-`__attribute__((always_inline))`*strongly* urges compilers to inline functions.
24
27
-`__builtin_unreachable()` is used to teach the optimizer which assumptions it can make about input arguments.
@@ -28,15 +31,15 @@ Here is how it is achieved in C:
28
31
- All operations become statically analyzable, reducing to constants.
29
32
-`assert()` calls get eliminated when conditions are provably true.
30
33
31
-
It's not actually "stack vs heap" that matters; what matters is whether the compiler can treat the buffer as a non-escaping, fully analyzable region of memory. Stack allocation makes that easy. Heap allocation only works in very simple cases where the pointer never escapes and all memory operations can be folded away.
34
+
[Link-time optimization](https://en.wikipedia.org/wiki/Interprocedural_optimization) with `-flto` should allow Clang and GCC to perform these optimizations even when the code is split across several object files.
32
35
33
-
The best use-case I can think of for this technique is generating lookup tables at compile-time, since functions like `sin()`*also* successfully get optimized away. This technique seems to also work fine however for implementing runtime-allocated data structures, without needing macros.
36
+
# Generic Stack
34
37
35
-
I added a `main()` function to the programs to prove that they don't crash on any `assert()`calls at runtime, but even when you remove `main()`the `fn_version()` and `macro_version()` functions get optimized just as hard.
38
+
In this program I use `malloc()`and `free()`in order to demonstrate that they can be optimized away too.
36
39
37
-
[Link-time optimization](https://en.wikipedia.org/wiki/Interprocedural_optimization) with `-flto` should allow Clang and GCC to perform these optimizations even when the code is split across several object files.
40
+
I added a `main()` function to the program to prove that it doesn't crash on any `assert()` calls at runtime.
38
41
39
-
# Generic Stack
42
+
It's important to note that `fn_version()` and `macro_version()` get optimized just as hard, even when you remove the `main()`.
40
43
41
44
Copy of the code on [Compiler Explorer](https://godbolt.org/z/fdf5acdcn):
0 commit comments