Правила программирования на С и С++. Главы 1-6 - Аргумент параметризированного макроса не должен появляться в правой части более одного раза

ОГЛАВЛЕНИЕ

 

83. Аргумент параметризированного макроса не должен появляться в правой части более одного раза.

Макрос SQUARE() даже в своем модифицированном виде представил выше серьезную проблему. Дано:

#define SQUARE(x) ((x)*(x))Выражение SQUARE(++x) дважды инкрементирует x. После чего макрос в этом случае дает неверный результат. Если x вначале содержит 2, то SQUARE(++x) вычисляется как 3 * 4. Такое поведение есть пример побочного эффекта макроса - ситуации, когда макрос ведет себя неожиданно.

SQUARE(++x) также показывает пример ситуации, в которой использование макроса просто слишком рискованно для оправдания сложностей сопровождения. Встроенная функция С++ или шаблон, расширяемый до встроенной функции, являются более лучшими решениями. Даже в С простую функцию с неудачными аргументами легче сопровождать, чем эквивалентный макрос:

double square( double x )

{

return x * x;

}

Но тем не менее, у меня есть серьезное сомнение в том, что использование функции для скрытия простого умножения является стоящим делом. 

83.1. Никогда не используйте макросы для символьных констант.

Например:

#define SPACE ' 'имеет смысл, если только вы намерены использовать вместо пробела другой символ (как если бы вы испытывали, например, программу для замены символов табуляции).

Никогда не делайте так:

#define SPACE 0x20

Действительное значение символьной константы для пробела (' ') изменяется компилятором так, чтобы оно соответствовало операционной среде, для которой ведется компиляция. Для среды, поддерживающей ASCII, это значение будет 0x20, а для EBDCDIC - уже нечто другое. Не думайте, что у какого-то символа свое постоянное значение.