https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92285
Bug ID: 92285 Summary: Layout of istreambuf_iterator subobject depends on -std mode Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: ABI Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redi at gcc dot gnu.org Target Milestone: --- The fix for PR 50336 (r178713) makes this program depend on the -std mode: #include <iterator> #include <iostream> struct I : std::iterator<std::input_iterator_tag, char> { }; struct J : I, std::istreambuf_iterator<char> { }; int main() { std::cout << sizeof(J) << '\n'; } For C++98 it prints 24 but for other modes it prints 16. The reason is that std::istreambuf_iterator has a different base class: template<typename _CharT, typename _Traits> class istreambuf_iterator : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, _CharT*, #if __cplusplus >= 201103L // LWG 445. _CharT> #else _CharT&> #endif This affects layout because std::iterator is an empty class, so whether the two base classes can share the same address depends on what istreambuf_iterator's base class is. This isn't a disaster, because in practice it is probably very rare for a type to have two std::iterator subobjects that could have the same address. But technically it's still an ABI incompatibility between C++98 and C++11/14/17 modes. The solution is to make istreambuf_iterator always have the same base class, but then conditionally override the reference member: template<typename _CharT, typename _Traits> class istreambuf_iterator : public iterator<input_iterator_tag, _CharT, typename _Traits::off_type, _CharT*, ???> { public: using reference = ???; Now the base class will always be the same, and so won't change layout when __cplusplus changes.