Есть ли гарантия, что каждый заголовок библиотеки выглядит примерно так?
#ifndef STDIO_H
#define STDIO_H
/* contents here... */
#endif
Не могли бы вы сослаться на источник?
Спасибо!
Есть ли гарантия, что каждый заголовок библиотеки выглядит примерно так?
#ifndef STDIO_H
#define STDIO_H
/* contents here... */
#endif
Не могли бы вы сослаться на источник?
Спасибо!
Нет, GCC не защищает вас от библиотеки, не использующей защиту включения, как вы описали, - это зависит от рассматриваемой библиотеки. (И не является частью GCC.)
Все известные стандартные библиотеки C (glibc, newlibc, ulibc) правильно защищают свои включения. (Поскольку они широко используются, такая вопиющая проблема будет быстро обнаружена.)
Изменить: после вашего второго комментария ваш вопрос теперь имеет больше смысла. Цитата из ISO/IEC 9899:1999 (C99), глава 7.1.2 Стандартные заголовки, параграф 4, первое предложение:
Стандартные заголовки могут быть включены в любом порядке; каждый из них может быть включен более одного раза в заданную область действия с тем же эффектом, что и включение только один раз, за исключением того, что эффект включения ‹assert.h› зависит от определения NDEBUG (см. 7.2).
Это означает, что если какая-либо стандартная библиотека C, с которой вы столкнулись, доставляет вам проблемы, она сломана.
В стандарте C99 (ISO/IEC 9899:TC3) конкретно указано:
Стандартные заголовки могут быть включены в любом порядке; каждый из них может быть включен более одного раза в заданную область действия с тем же эффектом, что и включение только один раз, за исключением того, что эффект от включения
<assert.h>
зависит от определения NDEBUG (см. 7.2).
Пункт 4 в разделе 7.1.2
Стандарт C++ определенно указывает, что заголовки стандартных библиотек могут быть включены #include более одного раза. Однако он не указывает, каким должен быть механизм, позволяющий избежать множественных определений. Я ожидаю, что стандарт C (которого у меня нет) говорит что-то подобное. Но почему вас это беспокоит?
pass1.h' and
pass1.c', а в pass1.c есть #include ‹stdio.h›, а также в pass1.h. Я знаю, что могу просто удалить #include ‹stdio.h› из pass1.c, потому что он уже включен в pass1.h, но мне было интересно, может ли что-то сломаться, если я этого не сделаю.
- person Ori Popowski; 23.07.2009
Существуют сценарии autoconf, написанные для введения защиты от многократного включения заголовочных файлов для исходных баз. Я уверен, что это будет сделано для стандартной библиотеки C.
Вот самый важный раздел, который я смог найти в наиболее последний черновик:
6.10.2 6 - Директива предварительной обработки #include может появиться в исходном файле, который был прочитан из-за директивы #include в другом файле, вплоть до предела вложенности, определенного реализацией (см. 5.2.4.1).
Затем в разделе 5.2.4.1 перечислены минимальные требуемые значения для различных ограничений окружающей среды; для включения вложенных файлов это 15.
Как это достигается, зависит от конкретной реализации; стандарт не предписывает использование охранников #include, хотя разумно предположить, что большинство реализаций делают это именно так.