This page is a snapshot from the LWG issues list, see theLibrary Active Issues List for more information and the meaning ofResolved status.
Section: 16[library]Status:ResolvedSubmitter: Martin SeborOpened: 2001-10-09Last modified: 2016-01-28
Priority:Not Prioritized
View otheractive issues in [library].
View all otherissues in [library].
View all issues withResolved status.
Discussion:
The synopses of the C++ library headers clearly show which names arerequired to be defined in each header. Since in order to implement theclasses and templates defined in these headers declarations of othertemplates (but not necessarily their definitions) are typicallynecessary the standard in 17.4.4, p1 permits library implementers toinclude any headers needed to implement the definitions in each header.
For instance, although it is not explicitly specified in the synopsis of<string>, at the point of definition of thestd::basic_string templatethe declaration of thestd::allocator template must be in scope. Allcurrent implementations simply include<memory> from within<string>,either directly or indirectly, to bring the declaration ofstd::allocator into scope.
Additionally, however, some implementation also include<istream> and<ostream> at the top of<string> to bring the declarations ofstd::basic_istream andstd::basic_ostream into scope (which are neededin order to implement the string inserter and extractor operators(21.3.7.9 [lib.string.io])). Other implementations only include<iosfwd>, since strictly speaking, only the declarations and not thefull definitions are necessary.
Obviously, it is possible to implement<string> without actuallyproviding the full definitions of all the templatesstd::basic_stringuses (std::allocator,std::basic_istream, andstd::basic_ostream).Furthermore, not only is it possible, doing so is likely to have apositive effect on compile-time efficiency.
But while it may seem perfectly reasonable to expect a program that usesthestd::basic_string insertion and extraction operators to alsoexplicitly include<istream> or<ostream>, respectively, it doesn't seemreasonable to also expect it to explicitly include<memory>. Sincewhat's reasonable and what isn't is highly subjective one would expectthe standard to specify what can and what cannot be assumed.Unfortunately, that isn't the case.
The examples below demonstrate the issue.
Example 1:
It is not clear whether the following program is complete:
#include <string>extern std::basic_ostream<char> &strm;int main () { strm << std::string ("Hello, World!\n");}or whether one must explicitly include<memory> or<ostream> (or both) in addition to<string> in order forthe program to compile.
Example 2:
Similarly, it is unclear whether the following program is complete:
#include <istream>extern std::basic_iostream<char> &strm;int main () { strm << "Hello, World!\n";}or whether one needs to explicitly include<ostream>, andperhaps even other headers containing the definitions of otherrequired templates:
#include <ios>#include <istream>#include <ostream>#include <streambuf>extern std::basic_iostream<char> &strm;int main () { strm << "Hello, World!\n";}Example 3:
Likewise, it seems unclear whether the program below is complete:
#include <iterator>bool foo (std::istream_iterator<int> a, std::istream_iterator<int> b){ return a == b;}int main () { }or whether one should be required to include<istream>.
There are many more examples that demonstrate this lack of arequirement. I believe that in a good number of cases it would beunreasonable to require that a program explicitly include all theheaders necessary for a particular template to be specialized, but Ithink that there are cases such as some of those above where it wouldbe desirable to allow implementations to include only as much asnecessary and not more.
[post Bellevue:]
Position taken in prior reviews is that the idea of a table of headerdependencies is a good one. Our view is that a full paper is needed todo justice to this, and we've made that recommendation to the issueauthor.
[2009-07 Frankfurt]
Proposed resolution:
For every C++ library header, supply a minimum set of other C++ libraryheaders that are required to be included by that header. The proposedlist is below (C++ headers for C Library Facilities, table 12 in17.4.1.2, p3, are omitted):
+------------+--------------------+| C++ header |required to include |+============+====================+|<algorithm> | |+------------+--------------------+|<bitset> | |+------------+--------------------+|<complex> | |+------------+--------------------+|<deque> |<memory> |+------------+--------------------+|<exception> | |+------------+--------------------+|<fstream> |<ios> |+------------+--------------------+|<functional>| |+------------+--------------------+|<iomanip> |<ios> |+------------+--------------------+|<ios> |<streambuf> |+------------+--------------------+|<iosfwd> | |+------------+--------------------+|<iostream> |<istream>, <ostream>|+------------+--------------------+|<istream> |<ios> |+------------+--------------------+|<iterator> | |+------------+--------------------+|<limits> | |+------------+--------------------+|<list> |<memory> |+------------+--------------------+|<locale> | |+------------+--------------------+|<map> |<memory> |+------------+--------------------+|<memory> | |+------------+--------------------+|<new> |<exception> |+------------+--------------------+|<numeric> | |+------------+--------------------+|<ostream> |<ios> |+------------+--------------------+|<queue> |<deque> |+------------+--------------------+|<set> |<memory> |+------------+--------------------+|<sstream> |<ios>, <string> |+------------+--------------------+|<stack> |<deque> |+------------+--------------------+|<stdexcept> | |+------------+--------------------+|<streambuf> |<ios> |+------------+--------------------+|<string> |<memory> |+------------+--------------------+|<strstream> | |+------------+--------------------+|<typeinfo> |<exception> |+------------+--------------------+|<utility> | |+------------+--------------------+|<valarray> | |+------------+--------------------+|<vector> |<memory> |+------------+--------------------+
Rationale:
The portability problem is real. A program that works correctly onone implementation might fail on another, because of different headerdependencies. This problem was understood before the standard wascompleted, and it was a conscious design choice.
One possible way to deal with this, as a library extension, wouldbe an<all> header.
Hinnant: It's time we dealt with this issue for C++0X. Reopened.