Правила разделяются на несколько категорий.
• Общие.
• Правила препроцессора.
• Правила использования имен и размещения текста.
• Правила для классов.
• Правила для функций и выражений.
• Правила для систем с жесткими условиями реального времени.
• Правила для систем, предъявляющих особые требования к вопросам безопасности.
Правила для систем с жесткими условиями реального времени и систем, предъявляющих особые требования к вопросам безопасности, применяются только в проектах, которые явно такими объявлены.
По сравнению с хорошими реальными стандартами программирования наша терминология является недостаточно точной (например, что значит, “система, предъявляющая особые требования к вопросам безопасности”), а правила слишком лаконичны. Сходство между этими правилами и правилами JSF++ (см. раздел 25.6.3) не является случайным; я лично помогал формулировать правила JSF++. Однако примеры кодов в этой книге не следуют этим правилам — в конце концов, книга не является программой для систем, предъявляющих особые требования к вопросам безопасности.
Общие правила
R100. Любая функция или класс не должны содержать больше 200 логических строк кода (без учета комментариев).
Причина: длина функции или класса свидетельствует об их сложности, поэтому их трудно понять и протестировать.
r101. Любая функция или класс должны помещаться на экране и решать одну задачу.
Причина. Программист, видящий только часть функции или класса, может не увидеть проблему. Функция, решающая сразу несколько задач, скорее всего, длиннее и сложнее, чем функция, решающая только одну задачу.
R102. Любая программа должна соответствовать стандарту языка С++ ISO/IEC 14882:2003(E).
Причина. Расширения языка или отклонения от стандарта ISO/IEC 14882 менее устойчивы, хуже определены и уменьшают переносимость программ.
Правила препроцессора
R200. Нельзя использовать никаких макросов, за исключением директив управления исходными текстами
#ifdef
и
#ifndef
.
Причина. Макрос не учитывает область видимости и не подчиняется правилам работы с типами. Использование макросов трудно определить визуально, просматривая исходный текст.
R201. Директива
#include
должна использоваться только для включения заголовочных файлов (
*.h
).
Причина. Директива
#include
используется для доступа к объявлениям интерфейса, а не к деталям реализации.
R202. Директивы
#include
должны предшествовать всем объявлениям, не относящимся к препроцессору.
Причина. Директива
#include
, находящаяся в середине файла, скорее всего, будет не замечена читателем и вызовет недоразумения, связанные с тем, что область видимости разных имен в разных местах разрешается по-разному.
R203. Заголовочные файлы (
*.h
) не должны содержать определение не константных переменных или не подставляемых нешаблонных функций.
Причина. Заголовочные файлы должны содержать объявления интерфейсов, а не детали реализации. Однако константы часто рассматриваются как часть интерфейса; некоторые очень простые функции для повышения производительности должны быть подставляемыми (а значит, объявлены в заголовочных файлах), а текущие шаблонные реализации требуют, чтобы в заголовочных файлах содержались полные определения шаблонов.
Правила использования имен и размещения текста
R300. В пределах одного и того же исходного файла следует использовать согласованное выравнивание.
Причина. Читабельность и стиль.
R301. Каждая новая инструкция должна начинаться с новой строки.
Причина. Читабельность.
Пример:
int a = 7; x = a+7; f(x,9); // нарушение
int a = 7; // OK
x = a+7; // OK
f(x,9); // OK
Пример:
if (p<q) cout << *p; // нарушение
Пример:
if (p<q)
cout << *p; // OK
R302. Идентификаторы должны быть информативными.
Идентификаторы могут состоять из общепринятых аббревиатур и акронимов.
В некоторых ситуациях имена
x
,
y
,
i
,
j
и т.д. являются информативными.
Следует использовать стиль
number_of_elements
, а не
numberOfElements
.
Венгерский стиль использовать не следует.
Только имена типов, шаблонов и пространств имен могут начинаться с прописной буквы.
Избегайте слишком длинных имен.
Пример:
Device_driver
и
Buffer_pool
.
Причина. Читабельность.
Примечание. Идентификаторы, начинающиеся с символа подчеркивания, зарезервированы стандартом языка С++ и, следовательно, запрещены для использования.
Исключение. При вызове функций из используемой библиотеки может потребоваться указать имена, определенные в ней.
Исключение. Названия макросов, которые используются как предохранители для директивы
#include
.
R303. Не следует использовать идентификаторы, которые различаются только по перечисленным ниже признакам.
• Смесь прописных и строчных букв.
• Наличие/отсутствие символа подчеркивания.
• Замена буквы O цифрой 0 или буквой D.
• Замена буквы I цифрой 1 или буквой l.
• Замена буквы S цифрой 5.
• Замена буквы Z цифрой 2.
• Замена буквы n буквой h.
Пример:
Head и head // нарушение
Причина. Читабельность.
R304. Идентификаторы не должны состоять только из прописных букв или прописных букв с подчеркиваниями.
Пример: BLUE и BLUE_CHEESE // нарушение
Причина. Имена, состоящие исключительно из прописных букв, широко используются для названия макросов, которые могут встретиться в заголовочных файлах применяемой библиотеки, включенных директивой.
Правила для функций и выражений
r400. Идентификаторы во вложенной области видимости не должны совпадать с идентификаторами во внешней области видимости.
Пример:
int var = 9; { int var = 7; ++var; } // нарушение: var маскирует var
Причина. Читабельность.
R401. Объявления должны иметь как можно более маленькую область видимости.
Причина. Инициализация и использование переменной должны быть как можно ближе друг к другу, чтобы минимизировать вероятность путаницы; выход переменной за пределы области видимости освобождает ее ресурсы.
R402. Переменные должны быть проинициализированы.
Пример: