views:

198

answers:

3

When there are many preprocessor statements and many #ifdef cascades, it's hard to get an overview since normally they are not indented. e.g.

#ifdef __WIN32__
#include <pansen_win32>
#else
#include <..>
#ifdef SOMEOTHER
stmts
#endif
maybe stmts
#endif

When I consider also indenting those preprocessor statements, I fear of getting confused with the general indentation level. So how do you solve this in a beautiful way?

+5  A: 

Just because preprocessing directives are "normally" not indented is not a good reason not to indent them:

#ifdef __WIN32__
    #include <pansen_win32>
#else
    #include <..>
    #ifdef SOMEOTHER
        stmts
    #endif
    maybe stmts
#endif

If you frequently have multiple levels of nesting of preprocessing directives, you should rework them to make them simpler.

James McNellis
+1  A: 

First, make sure you actually need all the ifdef statements. Perhaps there's a way to refactor them to keep the number of nested if checks limited? Assuming you do need them:

It would be a good idea to separate the first portion (the includes) into a separate include file:

In your_header.h:

#ifdef __WIN32__
#include <pansen_win32>
#else
#include <..>
#endif

Then in the implementation file, you can then keep things more sane. Liberal blank lines and comments are the approach I've typically taken regarding non-indented #ifdef checks.

#ifndef __WIN32__
#ifdef SOMEOTHER

stmts

// SOMEOTHER
#endif

maybe stmts

// __WIN32__
#endif

All that said, there's no rule that you can't indent preprocessor checks if it makes the code more readable.

Mark B
+2  A: 

As you, I didn't make my mind yet about the best way to indent, but I found in more than one place this alternative indentation in which the # is placed always at the first column and just the keyword is indented:

#ifdef __WIN32__
#  include <pansen_win32>
#else
#  include <..>
#endif

In Visual Studio, when you type # as the first character it always brings its indentation to the left, so it seems that MS either favors never indenting preprocessor statements, or using the above format.

The big problem is when you have non-preprocessor and preprocessor statements mixed and indentation applied. It's hard to make code that looks good, no matter which option:

option (a)

for (...)
{
  if (foo)
  {
    if (bar)
    {
#ifdef __WIN32__
      c = GetTickCount();
#else
      c = clock();
#endif
    }
  }
}

option (b)

for (...)
{
  if (foo)
  {
    if (bar)
    {
      #ifdef __WIN32__
      c = GetTickCount();
      #else
      c = clock();
      #endif
    }
  }
}

option (c)

for (...)
{
  if (foo)
  {
    if (bar)
    {
#     ifdef __WIN32__
        c = GetTickCount();
#     else
        c = clock();
#     endif
    }
  }
}

At this point, it becomes a question of personal taste, as so many other indentation styles.

Fabio Ceconello