https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80624
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- Some more examples of misbehaviour caused by eof() being a valid character: #include <sstream> #include <cassert> int main() { std::basic_ostringstream<char16_t> s; s.put(u'\uFFFF'); assert( s.str().length() == 1 ); } a.out: ex.cc:8: int main(): Assertion `s.str().length() == 1' failed. Aborted (core dumped) #include <sstream> int main() { std::basic_ostringstream<char16_t> s(u"foo"); s.exceptions(std::ios_base::badbit); s.put(u'\uFFFF'); } terminate called after throwing an instance of 'std::ios_base::failure' what(): basic_ios::clear Aborted (core dumped) #include <sstream> #include <cassert> int main() { const char16_t ffff = u'\uFFFF'; std::basic_istringstream<char16_t> s(u"\uFFFFoo"); s.exceptions(std::ios_base::eofbit); assert( s.rdbuf()->in_avail() > 1 ); auto c = s.get(); } terminate called after throwing an instance of 'std::ios_base::failure' what(): basic_ios::clear Aborted (core dumped)