include-what-you-use / include-what-you-use

A tool for use with clang to analyze #includes in C and C++ source files

Home Page:https://include-what-you-use.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

includes for `std::*stream` are treated as interchangeable

firewave opened this issue · comments

#include <istream>      // for std::ostream
#include <sstream>         // for std::basic_ostringstream, std::basic_istringstream, std::istringstream, std::ostringstream, std::ostream
#include <fstream>                // for std::basic_ostream, std::operator<<, std::basic_ofstream, std::basic_istream, std::basic_ifstream, std::endl, std::ofstream, std::basic_ios, std::ios, std::ostream, std::ifstream, std::operator|, std::ios_base

https://en.cppreference.com/w/cpp/io/basic_ostream

Occurs with 0.21 and 0.22.

Just to follow up, it seems like this is intentional:
https://github.com/include-what-you-use/include-what-you-use/blob/master/iwyu_include_picker.cc#L630

The mappings there are all public-to-public, which I believe means if the symbol is defined in $from, but you already have $to included, no action will be suggested.

Are you suggesting IWYU should be more rigid here and suggest the individual <*stream> headers even if their siblings are already included? I'm inclined to agree, but I'm not sure what practical problems the original mappings were added for.

Are you suggesting IWYU should be more rigid here and suggest the individual <*stream> headers even if their siblings are already included?

Yes.

I'm inclined to agree, but I'm not sure what practical problems the original mappings were added for.

As these mappings already existed over 12 years ago (that's already the age of the code just on the second blame) I assume those were just added because that's how they work in actual code. But I would consider this implementation-specific as it does not reflect what is documented as requirement for these symbols.

This looks quite similar to the public-to-public C mappings which are in the midst of being cleaned up right now.

I also assume this was partially done for convenience to reduce the amount of changes required to appease IWYU. But IMO that is not the goal of this tool. It is supposed to be verbose and granular about these things.

The opposite case would be transitive includes which technically also might not require actions because they "just work". But as highlighted by cleanups in the standard libraries in recent years that will start to come back at you at some point.

I also have the feeling that down the road we might end up at cases where iosfwd would be sufficient to use in a header. And these cases would be masked by the mappings in question. But let's take it one step at a time.

Even some confusion within the same file:

#include <iostream>          // for std::basic_ostream, std::cout, std::endl, std::istringstream
[...]
#include <sstream>           // for std::basic_istringstream