Я считаю, что хоть в каком-нибудь виде, но препроцессор необходим. Например, в заголовочных файлах Windows при определении различных констант и т.д часто определение зависит от версии Windows для которой компилируется программа, от того 32 битная или 64 битная программа, UNICODE или нет.
Вот кусок кода из WinUser.h
Код:
#if (_WIN32_WINNT >= 0x0500)
#define WM_MOUSELAST 0x020D
#elif (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
#define WM_MOUSELAST 0x020A
#else
#define WM_MOUSELAST 0x0209
#endif /* (_WIN32_WINNT >= 0x0500) */
Все эти комбинации по разным модулям разнести практически невозможно, так получится "комбинаторный взрыв".
Вот как раз для таких случаев был бы полезен препроцессор.
В ЧЯ уже есть встроенная возможность скрывать часть кода от компилятора. Достаточно выделить его из создать для него Fold (Toosl->Create Fold). Осталось лишь сделать условное открывани/закрывание этих фрагментов кода. И это было бы намного удобней чем текст наводненный всевозможными IFDEF. Выбрал нужную опцию и перед тобой текст именно в том виде, который будет с этой опцией скомпилирован. И что самое главное - это можно реализовать в виде примочки к среде, без внесения изменений в язык программирования.