It lets one source tree build differently per configuration with zero runtime cost, the excluded code isn't compiled at all, so there's no code-size or branch overhead on the device. The main uses: debug builds (#ifdef DEBUG wrapping logging and assertions that vanish in release), feature flags (compile a feature in or out per product SKU), and portability across hardware (#if defined(STM32F4) ... #elif defined(STM32H7) selecting register addresses, clock setups, or peripheral code for different chips and board revisions). You control the symbols from the build (-DDEBUG -DBOARD_REV=2), so the same codebase supports many targets without runtime configuration. #error is the companion tool, it halts the build with a message if no valid target is selected, catching misconfiguration at compile time rather than shipping a broken image. The discipline is to keep the #if thicket shallow, because deeply nested conditional compilation becomes unreadable and untestable.
C Programming · Interview question
How does conditional compilation help in embedded projects?
A strong answer
What a weak answer sounds like
You know the answer. Do you know what gets you dinged?
Pro breaks down the answer most candidates actually give to this question — and the specific reason an interviewer marks it down. It’s the difference between sounding correct and sounding senior, on all 472 questions.
From the lesson
The Preprocessor
Text substitution before the compiler ever runs: object and function macros, header guards, conditional compilation, and why a naive MAX macro evaluates its argument twice.