Friday, March 9, 2012

removing #ifdef's where possible

I am tickling developers about unreadable code, even
if its secure, the whole day at work. So its just fair
that I try to write code as clean as possible myself.
While there are different views on what resembles clean
code (in my personal view its the possibility to
add concurrency and new features without a large re-write
and still keeping an easy overview, IOW you can
refactor your code fast), conditional compilation is
usually seen as one of the evils.

Conditional compilation, aka #ifdef's, are even mentioned
in Effective C++. For small code snippets it might be acceptable,
but traditionally #ifdef's are used to make programs compile
on various UNIX flavors.That makes code unreadable and potentially
buggy, in particular if the #ifdef's guard different
call semantics for the same function, just like sendfile().

I decided to remove the #ifdef's alltogether from lophttpd,
by introducing a flavor namespace, and implementing a generic
function for each flavor. That moves the conditional
compilation logic to the Makefile or configure script.
Thats one of the commits for it.

No praying without paying: We buy the easy reading and clean
code by a little bit of code duplication for similar
flavors (for example sendfile() on Linux and Android flavor)
but thats at the time of writing/maintaining, not at runtime.
The other price is that you buy another function call
for code that could have been inlined. But as a whole,
thats cheap today, compared to the hassle one can have.

I am not banning #ifdef's, there are good reasons
for some of them and if you write code at the Linux driver-
(or rootkit-) level with a lot of API changes between
kernel versions, its sometimes the best way to go.
Yet, sometimes if you look at the code, it just feels wrong
and thats the point where you should change it.

No comments: