Bruno Desthuilliers said:
I'd say that the most professionnal way to do it is to put
platform-dependant code in separate modules, and to selectively include
and/or link the appropriate modules. The core logic should be readable
and understandable without having to worry about the target platform IMHO.
I concur. The core logic to impelement a task can even be done in a
different language from the implementation of the machine-dependent
code. (Implementing the core code in C and the hardware-specific code
in assembly, for example, or even writing the core code in Python and
the system-specific code in C.)
Of course, sometimes a finer grain of control is needed. Dividing your
code up should be done on a logical basis, not simply to dike out the
machine-specific stuff (they do not always coincide).
I do to. IMHO source code full of preprocessor directives is bad code.
#include statements are preprocessor directives.

I think you mean
code full of conditional compliation directives is bad code. On that,
I agree as well.
Conditional compilation can be used to remove sections of code that
are not relevant to a given environment but cannot be excised into
their own subroutines all the time. Not adding irrelevant sections to
a binary can reduce the size of the resulting program immensely, but
simply cutting the size shouldn't be a prime concern (usually).
In any case, any tool can be misused and any tool can be overused. The
C preprocessor is just complex enough to do the job it was built to do
and it does that job well. Using it to decide the logic of a program
is wrong, and using it to the exclusion of more elegant solutions is
also wrong.
So please can anyone help me in grasping the finer details of using
preprocessor directives to their maximum potential so that
professional C code no longer looks arcane to me.
Truly professional-quality [C or whatever] code should not look arcane
for an average [C or whatever] programmer, unless the algorithm is by
itself complex - and it then should be clearly documented.
I again agree. I also have a small caveat: If the algoritm becomes too
complex, some of the complexity may be shifted to the data the
algorithm processes. In my experience, a well-designed data format can
reduce the complexity of algorithms immensely.
Professionalism is about writing functionnal and maintainable code, not
half-obfuscated code relying on voodoo tricks. I personnaly think that
true simplicity is a virtue.
Yep. Simplicity is a virtue. I think a lot of programmers who create
voodoo code are trying to `optimize' certain areas that, like as not,
don't need to be optimized. Premature optimization is a great evil.
Optimization in general should only be done if it needs to be, and
only after the performance of each section of code has been carefully
measured.
That, or they're trying to win the IOCCC.
Now since I would certainly not pretend being a C guru, it may just
happens that what I view as complicated and obfuscated would seems
crystal clear to a good C programmer !-)
Heh. Usually not: Everyone's short-term memory can only hold an
average of seven items, plus or minus one. Code asking us to memorize
more causes an overflow condition and forces us to think much harder.
If code is confusing to an average C programmer, it's probably only
marginally more comprehenisble to a guru.