https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85269
--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> --- Your example in comment #2 should not warn. Projects often have their own "base" header that includes a a bunch of standard headers and that by convention is included in each of the project's source files so they don't have to worry about this kind of portability problem. I envision an algorithm that would look up the standard header where each standard symbol used in a translation unit is declared or defined and see if the standard header has been directly included at that point by some non-standard file; if not, the warning would trigger. I imagine there would need to be exceptions for the common cases you describe where this warning would be unhelpful, and the algorithm would need to be parameterized on the version of the standard to account for changes to the synopses of the headers. The <iosfwd> problem is interesting. A solution to it might involve a separate enhancement to the existing machinery. For example, in the following, GCC suggests to include <vector> (as expected) but doesn't provide a similar suggestion for the incomplete char_traits (which is required to be forward-declared in <iosfwd>). GCC also doesn't provide such a suggestion for std::string which isn't required to be declared in <iostfwd>. The warning should be able to differentiate these cases and trigger for any mention of std::string but avoid triggering for uses of std::char_traits that don't require it to be a complete type. This also suggests that for uses of types declared in <iosfwd> without the appropriate header included GCC might want to suggest to include <iosfwd> when the use doesn't require the type to be complete, rather than suggesting to include the header that defines the type. #include <iosfwd> enum { e0 = sizeof (std::char_traits<char>*), // okay, no warning e1 = sizeof (std::char_traits<char>), // warn if not error e2 = sizeof (std::basic_string<char>*), // warn e3 = sizeof (std::basic_string<char>), // warn if not error e4 = sizeof (std::vector<int>*), // warn if not error e5 = sizeof (std::vector<int>) // warn if not error }; pr85269.C:5:38: error: invalid application of ‘sizeof’ to incomplete type ‘std::char_traits<char>’ e1 = sizeof (std::char_traits<char>), // warn if not error ^ pr85269.C:8:39: error: invalid application of ‘sizeof’ to incomplete type ‘std::__cxx11::basic_string<char>’ e3 = sizeof (std::basic_string<char>), // warn if not error ^ pr85269.C:10:21: error: ‘vector’ is not a member of ‘std’ e4 = sizeof (std::vector<int>*), // warn if not error ^~~~~~ pr85269.C:10:21: note: ‘std::vector’ is defined in header ‘<vector>’; did you forget to ‘#include <vector>’? pr85269.C:2:1: +#include <vector> pr85269.C:10:21: e4 = sizeof (std::vector<int>*), // warn if not error ^~~~~~ pr85269.C:10:28: error: expected primary-expression before ‘int’ e4 = sizeof (std::vector<int>*), // warn if not error ^~~ pr85269.C:10:28: error: expected ‘)’ before ‘int’ e4 = sizeof (std::vector<int>*), // warn if not error ~ ^~~ )