Могу ли / должен ли я печатать все, что захочу после #ifndef? - PullRequest
0 голосов
/ 05 февраля 2019

Пример:

#ifndef HEADER_h
#define HEADER_h

#endif

Вместо HEADER_h, могу ли я сделать следующее?

#ifndef HEADER

или

#ifndef LIBRARY

или

#ifndef SOMETHING

или

#ifndef ANOTHERTHING

и т. Д.

Ответы [ 4 ]

0 голосов
/ 05 февраля 2019

Ваш пример - это так называемая защита заголовка, которая позволяет нам гарантировать, что содержимое заголовка включено только один раз.Однако это не единственное использование #ifndef. Вы можете использовать #ifndef для условной компиляции, как в

 #ifndef NO_DEBUG
 do_some_debug_stuff();
 #endif

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

0 голосов
/ 05 февраля 2019

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

// first.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void foo();

#endif

и еще один

// second.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H

void bar();

#endif

Когда вы включите оба в одну единицу перевода, один "выиграет", и его объявления будут видны,Например,

// main.cpp

#include "first.h" // now, NON_UNIQUE_H is defined
#include "second.h" // NON_UNIQUE_H already there, doesn't do anything

int main(int, char**)
{
    bar(); // error, won't compile, bar() isn't declared
}

Помимо необходимости обходить такие сценарии, лучше придерживаться некоторых соглашений в рамках всего проекта.Один из классических способов сделать это - преобразовать базовое имя файла заголовка в верхний регистр и добавить _H.Если у вас есть заголовочные файлы с одинаковым базовым именем в разных каталогах, вы можете включить имя каталога, например, SUBDIR_FOO_H и OTHERSUBDIR_FOO_H.Но это зависит от вас.

0 голосов
/ 05 февраля 2019

Защита заголовка - это просто соглашение, «хитрость», использующая условия препроцессора.При использовании защиты заголовка вы создаете макрос с именем и проверяете, был ли этот макрос уже определен.

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

Это не значит, что вы должны написать #ifndef URGLEBURGLE, хотя.Вы хотите, чтобы имя было полезным и уникальным , иначе нет особого смысла.

Обычно что-то вроде #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED - хорошая идея.

0 голосов
/ 05 февраля 2019

Вы можете использовать такую ​​конструкцию, как

#if !defined(HEADER) || !defined(LIBRARY)

На ваш вопрос вы используете

#ifndef HEADER_h
#define HEADER_h

#endif

Это то же самое, что и "#pragma Once". И да, вы можете использовать разныеимена определяет.В вашем случае LIBRARY , SOMETHING , HEADER_h - определяет, что вы можете установить в коде (#define MY_VAR_NAME) или с помощью параметров компилятора (флаг -DMY_VAR_NAME).

...