https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90126
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- I don't think this is a bug. If you tell gcc that the preprocessed output is preprocessed output, then the behaviour is consistent. So either: g++ -E namespace_anonymous_1_min_ok.cpp > temp_namespace_anonymous.ii g++ temp_namespace_anonymous.ii Or: g++ -E namespace_anonymous_1_min_ok.cpp > temp_namespace_anonymous.cpp g++ -x c++-cpp-output temp_namespace_anonymous.cpp The warning is suppressed when the type is defined in the "main input context" i.e. not in a header file. When you treat the preprocessed output as unpreprocessed source you end up with two sets of line markers, which makes GCC think the type is defined in a header. If you want to use preprocessed output this way you should probably generate it without line markers: g++ -E -P namespace_anonymous_1_min_ok.cpp > temp_namespace_anonymous.cpp g++ temp_namespace_anonymous.cpp