The beauty of the preprocessor #ifdef . . . #endif directives in C and C++ is that there are so many ways to abuse them.
I’ve been working on some vintage code (at least 15 years old) that provides a model for how not to do things. The compilation is controlled by no fewer than 750 #ifdef switches. Many of these are used in header files as guards against double inclusion, but the others roughly split into these jobs:
- controlling platform-specific code generation
- controlling project-specific code generation
- experimental features
- controlling different versions of hardware
The oddest of these switches are:
For the people who don’t like to document:
#ifdef __
For dyslexic programmers:
#ifdef DSTL_UPGRADES
#ifdef DTSL_UPGRADES
For those who think the code runs too quickly:
#ifdef INEFFICIENT
For those hopeful of a quick fix:
#ifdef MAKETHISWORK
For those who aren’t confident of our source control systems (and are dyslexic):
#ifdef OLD_SLOW_WAY
#ifdef ORIGINAL_CODE
#ifdef OROGINAL_CODE
#ifdef REDUNDANT_CODE
#ifdef REDUNDANT_FUNCTIONS
For those who can’t quite remember which operating system they are using:
#ifdef _vxworks
#ifdef __vxworks
#ifdef VXWORKS
#ifdef _VXWORKS
#ifdef __VXWORKS
For those trying the super-secret go-faster-stripes:
#ifdef WIN32_LEAN_AND_MEAN
For those who super unpositively don’t no way double negative want that code:
#ifdef _WIN32_trynot
. . . but just the once, or later, or huh, maybe not at all?:
#ifdef __JUSTONCE__
#ifdef _JUST_ONCE_
#ifdef notdef
#ifdef __NOTSMART_
#ifdef _NOTSMART_
#ifdef notyet
#ifdef NOTYET
#ifdef THIS_IS_NECESSARY
#ifdef THIS_IS_TOO_EXPENSIVE
Even the choice of names for include guards shows how coding standards change over time, or are ignored, or how the language standards themselves are ignored (the leading underscores):
xxx_inc_
_xxx_H_
__xxx_H__
xxx_include
xxx_H
xxx_inc
xxx_h
xxx_Hinc
_INC_xxx
INC_xxx