[Bug libstdc++/92285] New: Layout of istreambuf_iterator subobject depends on -std mode
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Oct 30 12:16:00 GMT 2019
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.
More information about the Gcc-bugs
mailing list