#include формат защиты заголовка? - PullRequest
20 голосов
/ 24 ноября 2008

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

#ifndef __FOO_HPP__
...

#ifndef INCLUDED_FOO_HPP
...

#ifndef SOME_OTHER_FORMAT

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

Ответы [ 13 ]

20 голосов
/ 24 ноября 2008

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

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

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

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

Итак, я остановился на

MYPROJECT_MODULE1_MISC_H_
MYPROJECT_MODULE2_MISC_H_

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

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

14 голосов
/ 24 ноября 2008

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

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

13 голосов
/ 24 ноября 2008

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

#ifndef GUARD_8D419A5B_4AC2_4C34_B16E_2E5199F262ED
10 голосов
/ 24 ноября 2008

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

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

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

(17.4.3.1.2/1)

4 голосов
/ 24 ноября 2008

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

#ifndef FOO_HPP
#define FOO_HPP

/* ... */

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

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

#pragma once
2 голосов
/ 24 ноября 2008

Я использую

 #if !defined(FOO_HPP_INCLUDED)

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

Также

 #ifndef __FOO_HPP__

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

1 голос
/ 25 ноября 2008

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

#ifndef path_to_file_h
#define path_to_file_h

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

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

1 голос
/ 24 ноября 2008

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

#ifndef FOO_HPP
#define FOO_HPP 1

...

#endif

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

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

НТН

ура

Rob

1 голос
/ 24 ноября 2008

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

#ifndef FOOBAR_CPP
...