As @salem suggests, more frequently one sees
1 2 3 4
|
#if ! defined SHIFT_REGISTER_USED
# define SHIFT_REGISTER_USED 1 // default behavior: use the shift register
#endif
// ...
|
This gives the user the ability to override the default by
a.) defining the macro before including the header; or
b.) defining the macro on the command line (for example, with option
-DUSE_SHR=1).
It could be that the default behavior is to raise an error via
#error, informing the user that they must define it to something.
Alternatively, instead of
#ifs, there may be a
#include "config.h" at the top of the header, where
config.h is a header file generated by a build tool like
autoconf or
cmake.
https://cmake.org/cmake/help/latest/command/configure_file.html
These tools are probably overkill for most projects.
You certainly want to limit the amount of conditional compilation. Try to provide a few big switches, not a million tiny knobs. You're on the hook to support every possible combination of choices.
If there are several distinct options, consider writing entirely separate implementation files, and compiling just one of them into the executable.