Compiler
The compiler module configures targets for strict C23 development. It enforces the C23 standard, enables a comprehensive set of warning flags, activates link-time optimization when the toolchain supports it, and controls symbol visibility for libraries.
This configuration implements the requirements defined in ADR-0002 — C as the Core Language, which mandates C23 as the minimum standard with strict warnings treated as errors, and ADR-0005 — CMake as the Build System, which specifies the exact compiler settings that all components must use.
Warning flags
When the module loads, it populates the STRICT_C_WARNING_FLAGS variable with a curated list of compiler flags.
These flags are organized by the category of problems they detect.
The base set enables the standard warning groups and treats every warning as an error, enforcing a zero-warnings policy across all components:
| Flag | Purpose |
|---|---|
-Wall | Enable all common warnings |
-Wextra | Enable extra warnings beyond -Wall |
-Wpedantic | Warn on non-standard C extensions |
-Werror | Treat all warnings as errors |
Undefined behavior detection flags catch implicit conversions, pointer misuse, and other sources of unpredictable behavior at compile time:
| Flag | Purpose |
|---|---|
-Wconversion | Implicit type conversions that may lose data |
-Wsign-conversion | Implicit signed/unsigned conversions |
-Wfloat-equal | Direct floating-point equality comparisons |
-Wcast-qual | Casts that remove a type qualifier |
-Wcast-align | Casts that increase required alignment |
-Wwrite-strings | String literal to non-const pointer conversions |
-Wpointer-arith | Arithmetic on void or function pointers |
-Wnull-dereference | Null dereference paths |
-Wdouble-promotion | Implicit float to double promotion |
-Wvla | Variable-length array usage |
C-specific correctness flags enforce modern function declaration practices, catching legacy K&R patterns that are a common source of subtle bugs:
| Flag | Purpose |
|---|---|
-Wstrict-prototypes | Require full prototypes in function declarations |
-Wmissing-prototypes | Global functions without a prior prototype |
-Wold-style-definition | K&R style function definitions |
-Wbad-function-cast | Casts to mismatched function return types |
Logic error flags help catch shadowing, incomplete switch coverage, and undefined preprocessor macros:
| Flag | Purpose |
|---|---|
-Wshadow | Local variable shadows another |
-Wswitch-enum | switch that doesn't handle all enum values |
-Wundef | Undefined macros used in #if directives |
Format string checking is set to its strictest level for security, catching potential buffer overflows and
injection vulnerabilities in printf-family calls:
| Flag | Purpose |
|---|---|
-Wformat=2 | Strict format string checking with security warnings |
GCC-specific flags
When the compiler is GCC, additional flags are enabled for deeper static analysis. These take advantage of GCC's more granular control over analysis levels:
| Flag | Purpose |
|---|---|
-Wformat-overflow=2 | Format string buffer overflows |
-Wformat-truncation=2 | Format string output truncation |
-Wformat-signedness | Format string sign mismatches |
-Wduplicated-cond | Duplicated conditions in if-else |
-Wduplicated-branches | Identical if-else branches |
-Wlogical-op | Suspicious logical operator usage |
-Wstrict-aliasing=3 | Strict type-based alias analysis |
-Wstrict-overflow=5 | Optimizations assuming no signed overflow |
-Warray-bounds=2 | Strict out-of-bounds array access detection |
-Wstringop-overflow=4 | Strict string operation buffer overflow detection |
-Wtrampolines | Trampoline generation (requires executable stack) |
-Wjump-misses-init | goto that skips variable initialization |
Clang-specific flags
When the compiler is Clang or AppleClang, a different set of additional flags is enabled. Some overlap with GCC's flags in purpose but use Clang's own analysis:
| Flag | Purpose |
|---|---|
-Wstrict-aliasing | Type-based aliasing violations |
-Wstrict-overflow | Signed overflow assumptions |
-Warray-bounds | Out-of-bounds array access |
-Wconditional-uninitialized | Conditionally uninitialized variables |
-Wassign-enum | Assigning values outside enum range |
-Wcomma | Suspicious comma operator usage |
-Wno-c2y-extensions | Suppress warnings for C2y extensions |
Link-time optimization
The module checks at load time whether the toolchain supports interprocedural optimization (LTO) using CMake's
CheckIPOSupported module. The result is
stored in STRICT_C_IPO_SUPPORTED. When LTO is supported, target_enable_strict_c23 enables it automatically
on every target it configures.
LTO allows the compiler to optimize across translation unit boundaries, producing smaller and faster binaries by eliminating dead code and inlining functions that would otherwise remain opaque.
Symbol visibility
For library targets (static, shared, module, or object), the module sets the
C visibility preset to hidden by
default. This means only symbols explicitly marked for export are visible to consumers — a best practice that
reduces symbol table size and avoids accidental API surface. For executable targets, no visibility preset is set.
You can override the default by passing the VISIBILITY parameter:
add_library(plugin MODULE src/plugin.c)
target_enable_strict_c23(plugin VISIBILITY default)
Function reference
target_enable_strict_c23
target_enable_strict_c23(<target> [VISIBILITY <visibility>])
Configures a target for C23 standard with strict warnings and LTO.
| Parameter | Description |
|---|---|
target | The CMake target to configure |
VISIBILITY | Symbol visibility preset: hidden, default, or protected (optional) |
The function sets the C standard to C23 (required), applies all STRICT_C_WARNING_FLAGS as private compile
options, enables interprocedural optimization if supported, and sets symbol visibility to hidden for library
targets unless VISIBILITY is specified.
add_library(mylib src/mylib.c)
target_enable_strict_c23(mylib)
add_executable(mytool src/main.c)
target_enable_strict_c23(mytool)
add_library(plugin MODULE src/plugin.c)
target_enable_strict_c23(plugin VISIBILITY default)
Variables defined
| Variable | Description |
|---|---|
STRICT_C_IPO_SUPPORTED | Whether interprocedural optimization (LTO) is supported by the toolchain |
STRICT_C_WARNING_FLAGS | List of compiler warning flags for strict C compilation |