Не указано, включает ли заголовок стандартной библиотеки произвольные заголовки?

Есть утверждение, в каких заголовках стандартной библиотеки 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

(...)
Другие вопросы по тегам