Стандарты программирования на С++. 101 правило и рекомендация
Шрифт:
макрос воспринимает так, будто ему переданы два аргумента, а именно
Макросы остаются единственно возможным решением для некоторых важных задач, таких как защита директивы
При условной компиляции (например, системно-зависимых частей) избегайте разброса по всему тексту директив
Можно (но осторожно) использовать макросы вместо большого количества копирований и вставок близких фрагментов кода.
Заметим, что [C99] и [Boost] включают соответственно умеренные и радикальные расширения препроцессоров.
[Boost] • [С99] • [Dewhurst03] §25-28 • [Lakos96] §2.3.4 • [Meyers96] §1 • [Stroustrup94] §3.3.1 • [Stroustrup00] §1.6.1, §7.8 • [Sutter02] §34-35 • [Sutter04] §31 • [Sutter04a]
17. Избегайте магических чисел
Избегайте использования в коде литеральных констант наподобие 42 или 3.1415926. Такие константы не самоочевидны и усложняют сопровождение кода, поскольку вносят в него трудноопределимый вид дублирования. Используйте вместо них символьные имена и выражения наподобие
Имена добавляют информацию и вводят единую точку сопровождения; в отличие от них дублированные по всей программе обычные числа анонимны и трудно сопровождаемы. Константы должны быть перечислениями или
Одно число 42 может не быть тем же числом 42, что и другое. Что еще хуже, программист может выполнять какие-то вычисления "в уме" (например: "Вот это 84 — просто удвоенное 42, которое было пятью строками ранее"), что совершенно запутывает код и делает последующую замену 42 другой константой источником огромного количества ошибок.
Лучше заменять такие жестко кодированные величины символьными константами. Строки лучше хранить отдельно от кода (например, в отдельном
Пример 1. Важные константы из предметной области на уровне пространств имен.
Пример 2. Константы, специфичные для данного класса. Вы можете определить
[Dewhurst03] §2 • [Kernighan99] §1.5 • [Stroustrup00] §4.8, §5.4
18. Объявляйте переменные как можно локальнее
Избегайте "раздувания" областей видимости. Переменных должно быть как можно меньше, а время их жизни — как можно короче. Эта рекомендация по сути является частным случаем рекомендации 10.
Переменные, время жизни которых превышает необходимое, имеют ряд недостатков.
• Они делают программу трудно понимаемой и сопровождаемой. Например, должен ли код обновлять строку path на уровне модуля, если изменен только текущий диск?
• Они засоряют контекст своими именами. Непосредственным следствием является то, что переменные на уровне пространства имен, наиболее видимые среди всех остальных, одновременно являются и наихудшими (см. рекомендацию 10).
• Они не всегда могут быть корректно инициализированы. Никогда не объявляйте переменную до того, как вы сможете корректно ее инициализировать. Неинициализированные переменные — источник "расползающихся" ошибок во всех программах С и С++, и требуют особого внимания в связи с тем, что не всегда могут быть обнаружены компилятором (см. рекомендацию 19).
В частности, старые версии языка С до [C99] требовали, чтобы переменные были определены только в начале области видимости; такой стиль в С++ вышел из употребления. Серьезная проблема такого ограничения состоит в том, что зачастую в начале области видимости не имеется достаточной информации для инициализации переменных. В результате у вас остается два выхода — либо инициализировать переменные некоторым значением по умолчанию (например, нулем), что обычно расточительно и может привести к ошибкам (если переменная будет использована до того, как приобретет некоторое осмысленное значение), либо оставить их неинициализированными, что опасно. Неинициализированная переменная пользовательского типа будет самоинициализироваться некоторым пустым значением.