Макросы остаются единственно возможным решением для некоторых важных задач, таких как защита директивы #include
(см. рекомендацию 24), использование директив #ifdef
и #if defined
для условной компиляции и реализация assert
(см. рекомендацию 68).
При условной компиляции (например, системно-зависимых частей) избегайте разброса по всему тексту директив #ifdef
. Вместо этого лучше организовать код таким образом, чтобы использование макросов обеспечивало возможность альтернативных реализаций одного общего интерфейса, который затем будет использоваться в программе.
Можно (но осторожно) использовать макросы вместо большого количества копирований и вставок близких фрагментов кода.
Заметим, что [C99] и [Boost] включают соответственно умеренные и радикальные расширения препроцессоров.
17. Избегайте магических чисел
Избегайте использования в коде литеральных констант наподобие 42 или 3.1415926. Такие константы не самоочевидны и усложняют сопровождение кода, поскольку вносят в него трудноопределимый вид дублирования. Используйте вместо них символьные имена и выражения наподобие width*aspectRatiо
.
Имена добавляют информацию и вводят единую точку сопровождения; в отличие от них дублированные по всей программе обычные числа анонимны и трудно сопровождаемы. Константы должны быть перечислениями или const
-значениями, с соответствующими областями видимости и именами.
Одно число 42 может не быть тем же числом 42, что и другое. Что еще хуже, программист может выполнять какие-то вычисления "в уме" (например: "Вот это 84 — просто удвоенное 42, которое было пятью строками ранее"), что совершенно запутывает код и делает последующую замену 42 другой константой источником огромного количества ошибок.
Лучше заменять такие жестко кодированные величины символьными константами. Строки лучше хранить отдельно от кода (например, в отдельном .срр
-файле или файле ресурса), что позволит непрограммистам просмотреть и обновить их, снижая количество дубликатов и помогая в интернационализации вашей программы.
const size_t PAGE_SIZE = 8192,
WORDS_PER_PAGE = PAGE_SIZE / sizeof(int),
INFO_BITS_PER_PAGE = 32 * CHAR_BIT;
// Файл widget.h
class Widget {
// Значение указано в объявлении
static const int defaultWidth = 400;
// Значение указано в определении
static const double defaultPercent;
static const char* Name() { return "widget"; }
};
// Файл widget.cpp
// Значение указано в определении
const double widget::defaultPercent = 66.67;
// Требуется объявление
const int widget::defaultWidth;
18. Объявляйте переменные как можно локальнее
Избегайте "раздувания" областей видимости. Переменных должно быть как можно меньше, а время их жизни — как можно короче. Эта рекомендация по сути является частным случаем рекомендации 10.
Переменные, время жизни которых превышает необходимое, имеют ряд недостатков.
•
•