On Tue, 19 May 2026 at 15:26, Jonathan Wakely <[email protected]> wrote:
>
> The standard explicitly requires the <ios> header to include <iosfwd>,
> which has declarations of all the standard stream buffers and stream
> types. Because we include <ios> in <istream> and <ostream>, this means
> that <iosfwd> is included everywhere, and so every iostream header has a
> forward declaration of every iostream type. This means that for example,
> <fstream> has a declaration (but not the definition) of std::stringbuf.
>
> This leads to a poor user experience, because the compiler's fixit hints
> for undeclared types do not trigger if the type _has_ been declared,
> instead users get an error about using an incomplete type. See the
> example in PR 125371, where using std::istringstream after including
> <fstream> fails to suggest including <sstream>.
>
> If we stop including <ios> in <istream> and <ostream>, and instead
> include _most_ of the same things that <ios> provides, then we can avoid
> the unhelpful declarations of the entire family of iostream types in
> every header. Users who really do want a declaration of std::filebuf
> or std::istringstream (but don't want the full definition) can still
> explicitly include <iosfwd> to get those declarations. But they won't
> get them as a side effect of <fstream> etc.
>
> We need to explicitly include <ios> in <iostream>.  The standard
> requires it there, and after this change we no longer get it via
> <istream> and <ostream>.
>
> libstdc++-v3/ChangeLog:
>
>         PR libstdc++/125371
>         * include/Makefile.am: Add new bits/iosfwd.h header.
>         * include/Makefile.in: Regenerate.
>         * include/bits/ostream.h: Replace <ios> with its constituent
>         parts, except for <iosfwd>.
>         * include/std/ios: Do not include <exception> or
>         <bits/char_traits.h>.
>         * include/std/iosfwd (ios_base, basic_ios, basic_streambuf)
>         (basic_istream, basic_ostream, basic_iostream): Move
>         declarations to new header.
>         * include/std/iostream: Include <ios>.
>         * include/std/istream: Replace <ios> with its constituent
>         parts, except for <iosfwd>.
>         * include/bits/iosfwd.h: New file.
> ---
>
> Tested x86_64-linux.
>
> Does this look like something we should do?

This patch isn't sufficient, because various headers still include all
of <ios> or <iosfwd>. I have a bigger patch that splits <iosfwd> into
five separate headers, so that e.g. <fstream> only needs to include
<bits/iosfwd_file.h> to get the relevant declarations, and doesn't
need the declarations that moved to <bits/iosfwd_string.h>.

I'll send it after testing ...

Reply via email to