The following prints "overflow": #include <sstream> #include <iostream> struct SB : std::stringbuf { int_type overflow(int_type c) override { std::cout << "overflow\n"; return std::stringbuf::overflow(c); } }; int main() { SB sb; std::ostringstream s; s.std::ios::rdbuf(&sb); s.put('a'); } The call to the virtual function should not be necessary when using the new ABI, because the SSO string has an initial non-zero capacity. The stringbuf could use it.
The fix is trivial: --- a/libstdc++-v3/include/std/sstream +++ b/libstdc++-v3/include/std/sstream @@ -99,7 +99,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 explicit basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out) : __streambuf_type(), _M_mode(__mode), _M_string() - { } + { +#if _GLIBCXX_USE_CXX11_ABI + _M_stringbuf_init(__mode); +#endif + } /** * @brief Starts with an existing string buffer. There was no point calling _M_stringbuf_init for the COW string, because immediately after construction there was no buffer to use. With an SSO string that isn't true.
This change would break a number of tests which were added specifically to ensure that the sequence pointers are all null after construction: https://gcc.gnu.org/ml/libstdc++/2004-09/msg00247.html I've reported a new issue to relax the requirements so we can make this change: https://wg21.link/lwg2995 This change would also fix Bug 81338 but for now I'll have to fix that in stringbuf::overflow, rather than optimising it to not call overflow.
GCC 8.1 has been released.
The C++2a draft now says: "It is implementation-defined whether the sequence pointers (eback(), gptr(), egptr(), pbase(), pptr(), epptr()) are initialized to null pointers."