Is the size of char_traits <char16_t> :: int_type not big enough?

Consider the following program:

#include <iostream>
#include <sstream>
#include <string>

int main(int, char **) {
  std::basic_stringstream<char16_t> stream;

  stream.put(u'\u0100');
  std::cout << " Bad: " << stream.bad() << std::endl;

  stream.put(u'\uFFFE');
  std::cout << " Bad: " << stream.bad() << std::endl;

  stream.put(u'\uFFFF');
  std::cout << " Bad: " << stream.bad() << std::endl;

  return 0;
}

Conclusion:

 Bad: 0                                                                                                                                                                                
 Bad: 0                                                                                                                                                                                
 Bad: 1  

It seems that the reason badbit is set is because put sets badbit if the character is std :: char_traits :: eof (). Now I can no longer put into the stream.

At http://en.cppreference.com/w/cpp/string/char_traits it says:

int_type: an integer type that can contain all char_type plus EOF values

But if char_type matches int_type (uint_least16_t), then how could that be true?

+4
source share
3 answers

, std::char_traits<char16_t>::int_type typedef std::uint_least16_t, . [char.traits.specializations.char16_t], :

eof() , , UTF-16.

, http://www.unicode.org/versions/corrigendum9.html, ++ all- char_traits<char16_t>::eof(), uint_least16_t 16 .

, , Character traits, std::char_traits<char16_t>::to_int_type(char_type) return U + FFFD U + FFFF. eof():

e , X::eq_int_type(e,X::to_int_type(c)) false c.

basic_streambuf<char16_t>::sputc(u'\uFFFF'), eof() u'\ufffd' .

. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80624, GCC.

, " UTF-16" , , , .

+5

, " ". char16_t ", , , , ". \uFFFF, " " , char16_t, , , . , .

+1

, :

stream.put(u'\uFFFF');

badbit, :

stream << u'\uFFFF';
char16_t c = u'\uFFFF'; stream.write( &c, 1 );

badbit.

.

, gcc bits/ostream.tcc, 164 ~ 165, , put() , eof(), badbit.

if (traits_type::eq_int_type(__put, traits_type::eof()))  // <== It checks the value!
    __err |= ios_base::badbit;

196 , write() , , .

.

From std::basic_ostream::put description :

Internally, the function performs an input sequence constructing a watchdog. Then (if good), it inserts c into its associated stream buffer object, as if calling its sputc member function, and finally destroys the guard object before returning.

He does not say anything about verification eof().

Therefore, I think that this is either an error in the document or an error in the implementation.

+1
source

Source: https://habr.com/ru/post/1676310/


All Articles