Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should #ifdef be avoided in .c files?

A programmer I respect said that in C code, #if and #ifdef should be avoided at all costs, except possibly in header files. Why would it be considered bad programming practice to use #ifdef in a .c file?

like image 920
Norman Ramsey Avatar asked Dec 05 '09 05:12

Norman Ramsey


People also ask

Why must we hire you for this job?

Show the employer that you've researched the job and understand what their role involves. Explain why you're a great fit for this position and its specific job requirements. Show them why you're excited about this type of work and will be motivated and enthusiastic in the role.

Why should we hire you as a student?

Example Answer #2My achievements in school and my after-school activities show that I am responsible, trustworthy, and a quick learner. I know that I can put these skills to good use working for you at your company.

Why should I hire you answer for fresher?

“I am a fast learner, have got good grasping skills, and I am really motivated. I am hard-working and punctual and will not at all take too much time to learn something new and implement it. I am also trained to meet deadlines due to my past internship.


1 Answers

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

E.g.

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

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

foo_w32.c:

void foo() {     // windows implementation } 

foo_psx.c:

void foo() {     // posix implementation } 

foo.h:

void foo();  // common interface 

Then have 2 makefiles1: Makefile.win, 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.

E.g.

common.h:

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) {      common_stuff();    } } 

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.
like image 106
Alex Budovski Avatar answered Oct 08 '22 18:10

Alex Budovski