Съдържание
Използването на предпроцесора има този недостатък, че компилаторът не работи директно с това, което сме написали и затова:
издава странни съобщения за грешка;
не проверява синтактичната коректност на цялата програма, а само на част;
не проверява типовете при макроси.
Вместо
#define pi 3.1415926
е по-добре да се използва
const float pi = 3.1415926;
Така компилаторът ще знае и типът, от който искаме да бъде константата.
Вместо
#define BLACK 0 #define WHITE 255 #define RED 34 #define BLUE 87 #define GREEN 148
е по-добре да се използва[14]
enum colors {black=0, red, blue, gree, white=255};
Друго предимство е, че при трасиране ще виждаме символни стойности като red и green, вместо непонятни числа.
Подобно, вместо да се използват параметризирани макроси, е по-добре да използваме функции. При тях е гарантирано, че аргументите ще се изчисляват само веднъж. Ако това е важно за ефективността на програмата, те може да бъдат обявени като inline, при което компилаторът ще генерира идентичен код, но ще може да извърши и по-пълен семантичен контрол върху програмата. Например вместо
#define abs(x) (((x)>=0)?(x):(-x))
е по-добре да използваме
inline int abs(int x) { return x >= 0 ? x : -x; }
Функцията abs ще работи коректно при използване на abs(i++), докато макросът ще увеличи аргумента двукратно.
Кога използваме условна компилация (#if, #ifdef, #ifndef)?
За поддържане на различни варианти на програмата (тестов/окончателен, различни числени методи Нютон/хорди, когато с тестове ще се установи кой вариант е най-удачният). Тук от всички варианти в крайна сметка се пуска само един.
За нагаждане към конкретната ОС и процесор
Когато е възможно, е по-добре да се използва обикновен условен оператор вместо условна компилация, защото така се проверява семантичната коректност на цялата програма, а не само на част.
Така например вместо
#ifdef HAS_FOO ... #else ... #endif
е по-добре да използваме
if (HAS_FOO) ... else ...
Модерните компилатори и в двата случая ще генерират идентичен код.
[14] В този пример е показано, че ако точната стойност на някои от константите не е важна, може и да не я уточняваме.