2008-11-24 2 views
19

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

#ifndef __FOO_HPP__ 
... 

#ifndef INCLUDED_FOO_HPP 
... 

#ifndef SOME_OTHER_FORMAT 

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

ответ

20

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

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

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

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

Так я поселился с

MYPROJECT_MODULE1_MISC_H_ 
MYPROJECT_MODULE2_MISC_H_ 

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

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

14

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

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

+0

Как я узнал, [двойные подчеркивания зарезервированы не только в начале] (https://stackoverflow.com/a/228797/2932052) – Wolf 2017-11-21 10:14:12

2

Я использую

#if !defined(FOO_HPP_INCLUDED) 

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

Также

#ifndef __FOO_HPP__ 

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

+0

Не уверен, что это получило проголосовать. Это не так, даже если бы я всегда использовал #ifndef вместо! Defined(), потому что нет требования использовать || или && в этом контексте. – 2008-11-24 19:28:38

1

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

#ifndef FOOBAR_CPP 
3

Если вы используете Visual Studio или компилятор Microsoft использовать прагму путь

#pragma once 
+0

И я был помечен как becaues .... Полностью верный и правильный ответ – JaredPar 2008-11-24 18:41:20

+0

Наверное, потому что это не переносимо. Используйте прагму, но включите в нее также защитников, на всякий случай вам понадобится использовать другой компилятор когда-нибудь. – KeithB 2008-11-24 18:44:18

+0

, потому что такой код заставит вас сразу же не дать мне интервью. – shoosh 2008-11-24 18:44:31

12

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

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED 
4

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

#ifndef FOO_HPP 
#define FOO_HPP 

/* ... */ 

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

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

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

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

(17.4.3.1.2/1)

1

Я также всегда что-то вдоль линий:

#ifndef FOO_HPP 
#define FOO_HPP 1 

... 

#endif 

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

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

НТН

веселит,

Роб

0

Я предпочитаю использовать:

#ifndef FILE_DATE_H_ 

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

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

#ifndef SOMEFILE_20082411_H_ 
1

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

#ifndef path_to_file_h 
#define path_to_file_h 

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

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

0

Я использую

<FILENAME_IN_ALL_CAPS>_<YYYYMMDD> 

или

<FILENAME_IN_ALL_CAPS>_INCLUDED_<YYYYMMDD> 

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

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

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

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

Вот один, что делает это для вас:

<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> 

так yourproject/include/yourlib/yourfile.hpp

становится YOURLIB_YOURFILE_HPP_INCLUDED

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

Смежные вопросы