Не указано, включает ли заголовок стандартной библиотеки произвольные заголовки?
Есть утверждение, в каких заголовках стандартной библиотеки C++ гарантированно включен другой заголовок?:
Заголовки стандартной библиотеки C++ могут включать друг друга неуказанными способами, поэтому программисты обычно не должны зависеть от одного заголовка, включая другой. [...]
На практике это имеет место. Например, <iostream>
может включать <string>
в других случаях нужно включить <string>
в явном виде. Тем не менее, я не могу найти, где в N4140 это так. Я посмотрел в:
- §2.9 [lex.header]
- §17.6.1.2 [заголовки]
- §17.6.2.2 [using.headers]
- §17.6.4.4 [alt.headers]
- §17.6.5.2 [res.on.headers]
Самое близкое, что я могу найти - это [using.headers]:
2 Единица перевода может включать заголовки библиотеки в любом порядке (пункт 2). Каждый может быть включен более одного раза, без эффекта, отличного от того, который был включен ровно один раз, за исключением того, что
<cassert>
или же<assert.h>
зависит каждый раз от лексически текущего определения NDEBUG.178
Но, похоже, это относится к программам на C++, а не к стандартной библиотеке:
[using.overview] / 1 В этом разделе описывается, как программа на C++ получает доступ к средствам стандартной библиотеки C++. [...]
А также [res.on.headers]:
1 Заголовок C++ может включать другие заголовки C++. Заголовок C++ должен содержать объявления и определения, которые появляются в его резюме. Заголовок C++, показанный в его кратком обзоре как включающий другие заголовки C++, должен предоставлять объявления и определения, которые появляются в кратких обзорах этих других заголовков.
Я думаю, что ключом является первое предложение, но оно не говорит явно, что это неуказанное поведение. Указывает ли это где-либо, что это неопределенное поведение, или это просто подразумевается?
1 ответ
Учитывая, что [res.on.headers] находится в стандарте C++14 под
17 Введение в библиотеку
17.6 Требования для всей библиотеки
17.6.5 Соответствующие реализации
17.6.5.2 Заголовки
кажется безопасным сказать, что "заголовки C++" в этом абзаце означают заголовки стандартной библиотеки C++. Этот термин следует понимать как противопоставление заголовкам C (то есть тем, которые обрабатываются из стандартной библиотеки C), которые в этом отношении менее свободны. [res.on.headers] говорит о них:
Стандартные заголовки C (D.5) должны включать только соответствующий им стандартный заголовок C++, как описано в 17.6.1.2.
Поскольку заголовок стандартной библиотеки C++ может включать в себя другие заголовки стандартной библиотеки C++, содержимое любого другого заголовка стандартной библиотеки может стать известным после включения другого, но если не указано, что заголовок должен включать в себя другой заголовок, это ненадежно. То, должен ли один заголовок включать другой, определяется на основе заголовка за заголовком. Например, для <iostream>
в [iostream.objects.overview] (27.4.1) говорится:
заголовок
<iostream>
конспект#include <ios> #include <streambuf> #include <istream> #include <ostream> (...)
И в [template.bitset] (20,7)
заголовок
<bitset>
конспект#include <string> #include <iosfwd> // for istream, ostream (...)