Подтвердить что ты не робот

#include формат защиты заголовка?

Я знаю, что это мало чем отличается от проекта, но, предполагая, что вы используете #defined защиты заголовка для вашего кода на С++, какой формат вы используете? например предполагая заголовок с именем foo.hpp:

#ifndef __FOO_HPP__
...

#ifndef INCLUDED_FOO_HPP
...

#ifndef SOME_OTHER_FORMAT

Я продаюсь по идее прописных #defines, но не могу установить формат для этих охранников.

4b9b3361

Ответ 1

Я всегда включал пространство имен или относительный путь в include guard, потому что только одно имя заголовка оказалось опасным.

Например, у вас есть большой проект с двумя файлами где-то в вашем коде

/myproject/module1/misc.h
/myproject/module2/misc.h

Итак, если вы используете согласованную схему именования для ваших включенных охранников, вы можете в конечном итоге иметь _MISC_HPP__, определенный в обоих файлах (очень забавно найти такие ошибки).

Итак, я поселился с

MYPROJECT_MODULE1_MISC_H_
MYPROJECT_MODULE2_MISC_H_

Эти имена довольно длинные, но по сравнению с болью двойных определений это того стоит.

Другой вариант, если вам не нужна независимость от компилятора/платформы, вы можете искать некоторые вещи #pragma после.

Ответ 2

Я всегда использую INCLUDED_FOO_HPP

Я бы не использовал двойной подчеркивающий, потому что начинаются вещи с двойными подчеркиваниями.

Ответ 3

Чтобы действительно избежать конфликтов имен, я использую GUID:

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED

Ответ 4

Лично я просто использую имя файла FOO_HPP. Google использует весь путь, такой как SRC_ENGINE_FAST_HPP.

Некоторые наборы имен и функций подписи всегда зарезервированы для реализация:

  • Каждое имя, содержащее двойной знак подчеркивания (_ _), или начинается с подчеркивание, за которым следует верхний регистр письмо (2.11) зарезервировано для для любого использования.
  • Каждое имя, начинающееся с символа подчеркивания, зарезервировано для реализации для использования в качестве имени в глобальное пространство имен.

(17.4.3.1.2/1)

Ответ 5

Я предпочитаю этот формат:

#ifndef FOO_HPP
#define FOO_HPP

/* ... */

#endif // FOO_HPP
  • Простой #ifndef вместо #if! defined (...), потому что редко имеет смысл использовать сложное условие для защиты заголовка.
  • Часть _HPP, чтобы пометить идентификатор в качестве защиты заголовка.
  • Отсутствуют ведущие символы подчеркивания, потому что такие идентификаторы (начиная с 2 символов подчеркивания или с 1 подчеркиванием и заглавной буквой) зарезервированы для реализации.
  • Базовая часть - это просто имя файла FOO. Однако для библиотечного кода, который будет использоваться повторно, рекомендуется добавить еще одну часть в начале. Обычно это пространство имен или имя модуля, например. MYLIB_FOO_HPP, и это помогает избежать конфликтов имен.

Ответ 6

Если вы используете Visual Studio или компилятор Microsoft, используйте метод pragma

#pragma once

Ответ 7

Я использую

 #if !defined(FOO_HPP_INCLUDED)

Я предпочитаю современный синтаксис defined, потому что он позволяет || && операторов, даже если они здесь не используются.

Кроме

 #ifndef __FOO_HPP__

является технически незаконным, так как ведущие символы подчеркивания зарезервированы.

Ответ 8

Я всегда использую

#ifndef FOOBAR_CPP

Ответ 9

Я также всегда использовал что-то вроде:

#ifndef FOO_HPP
#define FOO_HPP 1

...

#endif

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

Вам может понравиться отличная книга Джона Лакоса "Разработка программного обеспечения большого масштаба С++" (ссылка Amazon - дезинфицирована для script kiddy link nazis) для некоторых соображений, касающихся заголовка.

НТН

веселит,

Rob

Ответ 10

Когда мне платят за мое время, и еще нет стандартного для компании, я использую:

#ifndef path_to_file_h
#define path_to_file_h

Причиной для строчной буквы является то, что проще копировать и вставлять имена файлов и заменять косые черты символами подчеркивания. Причиной для #ifndef является то, что он хорошо сочетается С#define, что упрощает просмотр символов одинаковыми. Мне нравится идея GUID, поэтому я могу попробовать.

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

Ответ 11

Я обычно использую:

#ifndef FILE_DATE_H_

(замените _H_ соответствующим расширением, таким как _HPP_ и т.д.). Печать даты должна избегать столкновений с другими именованными заголовками в других направлениях/библиотеках.

поэтому в конце он выглядит следующим образом:

#ifndef SOMEFILE_20082411_H_

Ответ 12

Я использую

<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>

или

<FILENAME_IN_ALL_CAPS>_INCLUDED_<YYYYMMDD>

Сохранение синхронности с иерархиями папок слишком раздражает (друг рефакторинга), GUID слишком раздражает, суффикс даты достаточно хорош. Если бы я был в одинаковом названии файлов в тот же день, я бы

<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>a
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>b
<FILENAME_IN_ALL_CAPS>_<YYYYMMDD>...

Ответ 13

Я бы пошел с файловым движением + суффикс boost _INCLUDED плюс широко поддерживаемый в настоящее время #pragma once

В alot редакторах (для меня его возвышенное) вы также можете определить некоторые макросы/фрагменты для этого.

Вот один из них для вас:

<snippet>
    <content><![CDATA[
#ifndef ${1:${TM_FILEPATH/(.*\/(include|src))*([^a-zA-Z0-9_]+)*([a-zA-Z0-9_]+)([.])*([a-zA-Z0-9_]+)*/\U$4_$6/ig}_INCLUDED}
#define $1
#pragma once


$0


#endif // $1
]]></content>
    <tabTrigger>incguard</tabTrigger>
    <description>include guard</description>
</snippet>

so yourproject/include/yourlib/yourfile.hpp

становится YOURLIB_YOURFILE_HPP_INCLUDED

Дополнительный инструмент проверки стиля внешнего исходного кода может легко отслеживать последовательность ваших охранников таким образом.