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.

Reply via email to