Is it unspecified whether a standard library header includes arbitrary headers?
Asked Answered
S

1

8

There is a claim in Which headers in the C++ standard library are guaranteed to include another header?:

The C++ standard library headers may include each other in unspecified ways, so programmers generally shouldn't depend on one header including another. [...]

In practice this tends to be the case. For example, <iostream> may include <string>, in other cases you need to include <string> explicitly. However, I can't seem to find where in N4140 this is the case. I've looked in:

  • §2.9 [lex.header]
  • §17.6.1.2 [headers]
  • §17.6.2.2 [using.headers]
  • §17.6.4.4 [alt.headers]
  • §17.6.5.2 [res.on.headers]

The closest I can find is from [using.headers]:

2 A translation unit may include library headers in any order (Clause 2). Each may be included more than once, with no effect different from being included exactly once, except that the effect of including either <cassert> or <assert.h> depends each time on the lexically current definition of NDEBUG.178

But this seems to apply to C++ programs, not the standard library:

[using.overview]/1 This section describes how a C++ program gains access to the facilities of the C++ standard library. [...]

As well as [res.on.headers]:

1 A C++ header may include other C++ headers. A C++ header shall provide the declarations and definitions that appear in its synopsis. A C++ header shown in its synopsis as including other C++ headers shall provide the declarations and definitions that appear in the synopses of those other headers.

I think the key is the first sentence, but it doesn't explicitly say that it's unspecified behavior. Does it state anywhere that this is unspecified behavior or is it simply implied?

Stoltz answered 26/2, 2015 at 16:20 Comment(3)
Nobody ever claimed it was unspecified behavior. The claim in the other question is just that headers include each other in unspecified ways. That's not the same thing. Unspecified behavior is a very specific term describing (or not, as the case may be) the behavior of the compiled program.Kata
@SebastianRedl Poor wording on my part. I said "a claim", but not necessarily that he was saying it was unspecified behavior. Also, I think that everyone kind of assumed that it is unspecified behavior, saying that "it's unspecified" is a conflation of terms.Stoltz
@remyabel: "Unspecified" just means that nothing specifies it, which is the case. I doubt that "everyone" would conflate this use of a regular English word with the standard's term "unspecified behaviour", which specifically refers to the behaviour of a program, not an implementation. I certainly wouldn't.Belier
E
4

Given that [res.on.headers] is found in the C++14 standard under

17 Library Introduction

17.6 Library-wide requirements

17.6.5 Conforming implementations

17.6.5.2 Headers

it seems safe to say that "C++ headers" in this paragraph means C++ standard library headers. The term is to be understood as opposed to C headers (i.e., those cargo-culted from the C standard library), which are less free in this regard. [res.on.headers] says about them:

The C standard headers (D.5) shall include only their corresponding C++ standard header, as described in 17.6.1.2.

Since a C++ standard library header may include other C++ standard library headers, the contents of any other standard library header may become known after including another, but unless it is stated that a header must include another header, this is not reliable. Whether one header must include another is defined on a header-by-header basis. For example, for <iostream> it says in [iostream.objects.overview] (27.4.1):

Header <iostream> synopsis

#include <ios>
#include <streambuf>
#include <istream>
#include <ostream>

(...)

And in [template.bitset] (20.7)

Header <bitset> synopsis

#include <string>
#include <iosfwd>        // for istream, ostream

(...)
Expert answered 26/2, 2015 at 16:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.