#include формат защиты заголовка?
Я знаю, что это мало чем отличается от проекта, но, предполагая, что вы используете #defined защиты заголовка для вашего кода на С++, какой формат вы используете? например предполагая заголовок с именем foo.hpp
:
#ifndef __FOO_HPP__
...
#ifndef INCLUDED_FOO_HPP
...
#ifndef SOME_OTHER_FORMAT
Я продаюсь по идее прописных #defines, но не могу установить формат для этих охранников.
Ответы
Ответ 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
Дополнительный инструмент проверки стиля внешнего исходного кода может легко отслеживать последовательность ваших охранников таким образом.