Norman Ramsey Norman Ramsey - 1 month ago 7x
C Question

Why should #ifdef be avoided in .c files?

A programmer I respect said that in C code,

should be avoided at all costs, except possibly in header files. Why would it be considered bad programming practice to use
in a .c file?


Hard to maintain. Better use interfaces to abstract platform specific code than abusing conditional compilation by scattering #ifdefs all over your implementation.


void foo() {
#ifdef WIN32
   // do Windows stuff
   // do Posix stuff
   // do general stuff

Is not nice. Instead have files foo_w32.c and foo_psx.c with


void foo() {
    // windows implementation


void foo() {
    // posix implementation


void foo();  // common interface

Then have 2 makefiles1:, Makefile.psx, with each compiling the appropriate .c file and linking against the right object.

Minor amendment:

If foo()'s implementation depends on some code that appears in all platforms, E.g. common_stuff()2, simply call that in your foo() implementations.



void common_stuff();  // May be implemented in common.c, or maybe has multiple
                      // implementations in common_{A, B, ...} for platforms
                      // { A, B, ... }. Irrelevant.

foo_{w32, psx}.c:

void foo()  {  // Win32/Posix implementation
   // Stuff
   if (bar) {

While you may be repeating a function call to common_stuff(), you can't parameterize your definition of foo() per platform unless it follows a very specific pattern. Generally, platform differences require completely different implementations and don't follow such patterns.

  1. Makefiles are used here illustratively. Your build system may not use make at all, such as if you use Visual Studio, CMake, Scons, etc.
  2. Even if common_stuff() actually has multiple implementations, varying per platform.