2013-06-25 1 views
8

Каков обычный способ настройки ваших охранников? Я обычно пишу их как (например.h):Включить охранные соглашения в C

#ifndef _EXAMPLE_H_ 
#define _EXAMPLE_H_ 
#include "example.h" 
#endif 

Подчеркивает ли это соглашение? Я видел противоречивую информацию, когда я искал это. Нужно ли соответствовать имени заголовка?

+2

Я считаю, что это уже было полностью покрыто [здесь] (http://stackoverflow.com/questions/4867559/naming-include-guards). –

+0

Или еще лучше, если вы ищете более обширное освещение темы, рассмотрите http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#The__define_Guard. Вы также можете прочитать руководство по стилю google, как ссылку –

ответ

15
Does underscore convention matter? 

Да. Это важно.

Идентификаторы с ведущим знаком подчеркивания, за которым следует буква верхнего регистра, зарезервированы для реализации. Таким образом, у вас возникнет неопределенное поведение .

Ниже приводится спецификация стандарта Си для именования идентификаторов (C11 draft):

7.1.3 Зарезервированные идентификаторы

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

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

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

- Каждое имя макроса в любом из следующих подпунктов (включая направления будущих библиотек ) зарезервировано для использования, как указано, если включен какой-либо из связанных с ним заголовков; если явно не указано иное (см. 7.1.4). - Все идентификаторы с внешней связью в любом из следующих подпунктах (включая будущие направления библиотек) и errno всегда зарезервированы для использования в качестве идентификаторов с внешним linkage.184). - Каждый идентификатор с областью файлов, указанным в любом из , следующих подзаголовки (включая будущие направления библиотек) - это , зарезервированные для использования в качестве имени макроса и как идентификатор с областью файлов в том же пространстве имен, если включен какой-либо из его связанных заголовков.

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

Если программа удаляет (с #undef) любое определение макроса идентификатора в первой группе, указанной выше, поведение не определено.

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

+2

. Одно общее соглашение - сопоставить имя заголовка в верхнем регистре и заменить '.h' на' _H', поэтому охранник для 'foobar.h' будет' FOOBAR_H'. Если имя начинается с «e», например «elvis.h», то защитным макросом будет «ELVIS_H» - и макросы, начинающиеся с буквы «E», и цифра или буква в верхнем регистре зарезервированы для использования «» '. Совершенно маловероятно, что реализация определит «ELVIS_H» как код ошибки, но вы можете избежать этой возможности, используя соглашение, подобное 'H_HEADER_NAME', а не' HEADER_NAME_H'. –

-1

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

Технически, как сказал KingsIndian, идентификаторы, начинающиеся с подчеркивания зарезервированы:

правилам, перефразировать из ANSI п. 4.1.2.1, являются: (?)

1. All identifiers beginning with an underscore followed 
    by an upper-case letter or another underscore are always 
    reserved (all scopes, all namespaces). 
2. All identifiers beginning with an underscore are reserved 
    for ordinary identifiers (functions, variables, typedefs, enumeration 
    constants) with file scope. 
... 

comp.lang.c FAQ list · Question 1.29

Может быть, новый ISO C11 стандарт расслабляет эти правила, но это было в нижней строке на некоторое время.

+0

-1. Это не правило о символах подчеркивания. И если вы не начинаете с подчеркивания, но используете UUID, вы, вероятно, начнете с цифры. – Potatoswatter

+0

Не сырой UUID, а что-то вроде 'INCLUDED_AF3430340AB3012FE0DEADBEEF'. –

+0

Идентификаторы, начинающиеся с символа подчеркивания, за которым следует либо второе подчеркивание, либо буква верхнего регистра, зарезервированы для любого использования. Все идентификаторы, начинающиеся с символа подчеркивания, зарезервированы для использования в качестве идентификаторов с областью файлов как в обычном, так и в имени тегов. Хорошо знать точные правила, но разумно быть консервативным и просто избегать определения * ничего *, начиная с подчеркивания. –