У вас есть инструкции препроцессора ifdef или ifndef из стандартной библиотеки C ++?

Я создаю свой собственный проект терминального приложения на C ++ и спрашиваю себя, есть ли в стандартной библиотеке инструкции препроцессоров ifdef или ifndef. Я хочу знать, что, поскольку мне нужно создавать разные файлы заголовков, для которых нужны некоторые заголовки стандартной библиотеки, такие как «строка» и некоторые другие, я не хочу включать одну и ту же библиотеку 3 или более раз, потому что это делает программу тяжелее. < br /> Например, я написал в своих заголовочных файлах что-то вроде этого, чтобы предотвратить включение файла .h более одного раза:

#ifndef myheader_h
#define myheader_h
    // my file code here
#endif

Я попытался скомпилировать, но компилятор ничего не сказал мне об ошибках или предупреждениях.
Я также попытался прочитать исходный код стандартной библиотеки (https://en.cppreference.com/w/cpp/header) и я не нашел ни одного правила препроцессора, такого как ifdef или ifndef.
Стоит ли включать стандарт такие заголовки библиотеки?

#ifndef string_h
#define string_h
    #include <string>
#endif

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

Обновления

Для тех, кто сказал «вы не в том положении, о котором вам нужно беспокоиться» и кто сказал «это стоит очень мало, если у него есть надлежащая защита», я означало: важна тяжесть программы, я хочу сделать ее более легкой, поэтому не хочу полностью включать один и тот же файл несколько раз. Имеют ли файлы std lib собственно охранники? (у моих файлов заголовков они есть, я не знал файлов std lib)


person M. Petri    schedule 13.08.2018    source источник
comment
Вы неправильно понимаете, как работают охранники включения. Вам не нужно думать об этом ни с одним заголовком, кроме того, который вы пишете. См. Пример en.wikipedia.org/wiki/Include_guard.   -  person alter igel    schedule 13.08.2018
comment
я не хочу включать одну и ту же библиотеку 3 или более раз, потому что это делает программу тяжелее. звучит так, будто вы не совсем в том положении, когда вам нужно беспокоиться о том, что ваша программа будет тяжелой (однако вы определите это) для начала.   -  person Baum mit Augen    schedule 13.08.2018
comment
<string> уже включает такую ​​же (или похожую) конструкцию. Самостоятельно писать еще один не нужно.   -  person HolyBlackCat    schedule 13.08.2018
comment
Многократное включение одного и того же заголовка стоит очень мало (так как в нем можно пренебречь), если у него есть надлежащая защита включения.   -  person Jesper Juhl    schedule 13.08.2018


Ответы (3)


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

«Исходный код», который вы читаете, - это просто документация, в которой говорится, как должны работать файлы заголовков, но не предоставляется фактический код. Чтобы увидеть код, вы можете посмотреть файлы заголовков, предоставленные вашим компилятором. Например, заголовок <iostream> в Visual Studio имеет и #pragma once, и защиту заголовка:

#pragma once
#ifndef _IOSTREAM_
#define _IOSTREAM_
//...
#endif /* _IOSTREAM_ */

Заголовки, предоставляемые компилятором GCC, также имеют защиту заголовков:

#ifndef _GLIBCXX_IOSTREAM
#define _GLIBCXX_IOSTREAM 1
//...
#endif /* _GLIBCXX_IOSTREAM */
person BessieTheCookie    schedule 13.08.2018

Для стандартных файлов заголовков не требуется #define какие-либо определенные символы препроцессора, чтобы гарантировать, что они могут быть #included несколько раз.

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

Оказывается, это требование стандарта для большинства заголовков (Спасибо, @ Rakete1111).

Из стандарта C ++

Единица перевода может включать заголовки библиотек в любом порядке ([lex]). Каждый может быть включен более одного раза, при этом эффект не отличается от включения только один раз, за ​​исключением того, что эффект включения либо <cassert>, либо <assert.h> зависит каждый раз от лексически актуального определения NDEBUG.

Более того, они, скорее всего, будут использовать директиву #pragma once. Следовательно, даже если вы используете #include несколько раз для одного и того же заголовка, они будут прочитаны только один раз.

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

person R Sahu    schedule 13.08.2018
comment
Каждый может быть включен более одного раза, при этом эффект не отличается от включения только один раз, [...]. Таким образом, уже существует требование использования какой-либо защиты заголовка (eel.is/ c ++ draft / using.headers # 2) - person Rakete1111; 13.08.2018

Я спрашиваю себя [sic], есть ли в стандартной библиотеке инструкции препроцессора ifdef или ifndef

Стандарт не указывает, существуют ли средства защиты заголовков в стиле ifdef, хотя он требует, чтобы множественное включение каким-либо образом защищалось. Я взглянул на случайный заголовок реализации стандартной библиотеки stdlibc ++. У него есть защита жатки.

я не хочу включать одну и ту же библиотеку 3 или более раз, потому что это делает программу тяжелее

Многократное включение файла заголовка не делает программу «тяжелее».

Должен ли я включать такие заголовки стандартной библиотеки?

#ifndef string_h
#define string_h
    #include <string>
#endif

В этом нет необходимости или особенно полезно.

person eerorika    schedule 13.08.2018