Часть 1. Вступление

Часть 10. Форматирование
Часть 11. Исключения из правил


Эта статья является переводом части руководства Google по стилю в C++ на русский язык.
Исходная статья (fork на github), обновляемый перевод.

Исключения из правил


Соглашения по кодированию, описанные выше являются обязательными. Однако, как и в любых правилах, иногда в них есть исключения, которые сейчас и обсудим.

Существующий код, не соответствующий стилю


Допустимо отклоняться от правил, если производится работа с кодом, не соответствующим этому руководству.

Если модифицируется код, написанный другим стилем, допустимо отклоняться от требований этого руководства и использовать «местный» стиль, чтобы получить согласованный код. Если сомневаетесь — спросите автора кода (или того, кто это поддерживает). Помните, что согласованность включает также и текущий стиль кода.

Программирование под Windows


Программисты под Windows могут использовать особенный набор соглашений о кодировании, основанный на стиле заголовочных файлов в Windows и другом коде от Microsoft. Так как хочется сделать, чтобы код был понятным для всех, то рекомендуется использовать единое руководство по стилю в C++, одинаковое для всех платформ.

Повторим несколько рекомендаций, которые отличают данное руководство от стиля Windows:

  • Не используйте венгерскую нотацию (например, именование целочисленной переменной как iNum). Вместо этого используйте соглашения об именовании от Google, включая расширение .cc для файлов с исходным кодом.
  • Windows определяет собственные синонимы для базовых типов, такие как DWORD, HANDLE и др. Понятно, что при вызове Windows API рекомендуется использовать именно их. И всё равно, старайтесь определять типы, максимально похожие на C++. Например, используйте const TCHAR * вместо LPCTSTR.
  • При компиляции кода с помощью Microsoft Visual C++ установите уровень предупреждений 3 или выше. Также установите настройку, чтобы трактовать все предупреждения как ошибки.
  • Не используйте #pragma once. Вместо этого используйте стандартную защиту от повторного включения, описанную в руководстве от Google. Компоненты пути в имени для макроопределения защиты должны быть относительными к корню проекта.
  • Вообще, не используйте нестандартные расширения, такие как #pragma и __declspec (исключение для случаев крайней необходимости). Использование __declspec(dllimport) и __declspec(dllexport) допустимо, однако следует оформить их как макросы DLLIMPORT и DLLEXPORT: в этом случае их можно легко заблокировать, если код будет распространяться.

С другой стороны, есть правила, которые можно нарушать при программировании под Windows:

  • Обычно рекомендуется не использовать множественное наследование реализации; однако это требуется при использовании COM и некоторых классов ATL/WTL. В этом случае (при реализации COM или ATL/WTL) нарушение правила допустимо.
  • Хотя использование исключений в собственном коде не рекомендуется, они интенсивно используются в ATL и некоторых STL (в том числе и в варианте библиотеки от Visual C++). Когда используете ATL, следует определить _ATL_NO_EXCEPTIONS, чтобы запретить исключения. Желательно разобраться, можно ли запретить исключения и в STL, однако, если это не реализуемо, то допустимо разрешить исключения в компиляторе. (Учтите, что это разрешено только для компиляции STL. Пользовательский код всё равно не должен содержать обработчики исключений).
  • Типичный способ работы с прекомпилированными заголовочными файлами — включить такой файл первым в каждый файл исходников, обычно с именем StdAfx.h или precompile.h. Чтобы не создавать проблем при распространении кода, лучше избегать явного включения такого файла (за исключением precompile.cc). Используйте опцию компилятора /FI для автоматического включения такого файла.
  • Заголовочный файлы ресурсов (обычно resource.h), содержащий только макросы, может не следовать рекомендациям этого руководства.


Заключение


Руководствуйтесь здравым смыслом и придерживайтесь ПОСТОЯНСТВА в стиле.

Если редактируете чужой код, то потратьте несколько минут и ознакомьтесь со стилем этого кода. Если в нём используются пробелы вокруг if — следует делать также. Если комментарий отчёркнут линией из звёздочек, то в свой комментарии также следует добавить такую линию.

Основное предназначение руководства по стилю — это единый базис, это общий словарь, позволяющий не отвлекаться на вопросы "… как это написать ..." и сосредоточиться на том, что написать. Здесь были описаны общие правила стиля, однако не стоит забывать и о текущем используемом стиле. Если в существующем коде делаются исправления, которые сильно отличаются от исходного кода, это усложняет чтение кода, сбивает с ритма. Постарайтесь этого избежать.



Примечания:
Изображение взято из открытого источника.

Комментарии (6)


  1. Reformat
    31.10.2021 07:30
    +6

    Не используйте #pragma once. Вместо этого используйте стандартную защиту от повторного включения, описанную в руководстве от Google. Компоненты пути в имени для макроопределения защиты должны быть относительными к корню проекта.

    Какие-то вредные советы.


    1. NN1
      31.10.2021 07:57

      Вполне возможная причина это компиляторы, неподдерживающие эту прагму.

      Гугл компания немолодая, мало ли какое старьё у них в закромах :)


      1. VXP
        31.10.2021 12:28
        +2

        Даже компилятор из поставки Visual C++ 6.0 поддерживает


        1. SShtole
          31.10.2021 21:20

          И, кстати, насколько позволяет вспомнить мой склероз, в исходниках, которые генерировала VC6, комбинировались оба подхода: в хедер в начале записывалась прагма, а остальная часть включалась в #ifdef-«скобки» (извините, что я использую такое просторечное выражение вместо гугловского «макроопределение защиты» 8-P).


          1. NN1
            06.11.2021 13:40
            +1

            Это правильный и переносимый вариант.

            ifdef умеют все компиляторы, а если знакомы с pragma once, то используем.

            И волки сыты и овцы целы.


  1. SShtole
    31.10.2021 09:01
    +4

    Не используйте венгерскую нотацию (например, именование целочисленной переменной как iNum)

    Это НЕ венгерская нотация, а то, что с ней стало, когда она попала в руки профанов. Изначально Чарльз Симоньи предлагал использовать такие префиксы, как rw для записей (rows), например, rwPosition, us (unsafe string) для строк, нуждающихся в санации (на предмет инъекций и т.п.), d (delta) для разницы зачений, например, dY. Большинство префиксов были семантические и никакой IDE никогда не смог бы верно указать эту семантику при наведении курсора. (Как любят аргументировать противники венгерки). Ну, разве что такие префиксы как pX говорят о типе, но тип указателя — сам по себе семантический.

    Потом всё это дело опопсело и упростилось, и действительно стало дублировать информацию о типе, после чего венгерка разделилась на т.н. прикладную и системную. Последнюю иначе как профанацией идеи назвать трудно.

    Что касается первой, она, насколько можно судить, во многих местах жива и поныне. Просто теперь префикс принято записывать целиком, не экономя ширину экрана: deltaY и т.д.

    Составителям правил оформления, тем более из Гугл, знать такие тонкости, по идее, не помешало бы.