Почему потоки C++ используют char вместо unsigned char?
Я всегда задавался вопросом, почему стандартная библиотека C++ использует тип char
для реализации basic_[io]stream
и всех его вариантов, а не unsigned char
. Тип char
может быть как знаковым, так и беззнаковым, в зависимости от реализации, что может привести к переполнению и недополнению при таких операциях, как get()
, и, как следствие, к неопределённому значению переменных, участвующих в этих операциях. Другой пример — когда вы хотите вывести байт в неформатированном виде в ostream
, используя функцию put
.
Есть ли у кого-то идеи по этому поводу?
Примечание: Я всё ещё не совсем уверен. Поэтому, если у вас есть окончательный ответ, вы, конечно, можете его опубликовать.
2 ответ(ов)
Возможно, я неверно понял вопрос, но преобразование из unsigned char
в char
не является неопределенным, оно зависит от реализации (как указано в стандарте C++ 4.7-3).
Тип 1-байтового символа в C++ — это char
, а не unsigned char
. Это дает реализациям немного больше свободы для выбора наилучшего варианта на данной платформе (например, возможно, комитет по стандартам считал, что на некоторых ЦПУ арифметика со знаковыми байтами быстрее, чем со знаковыми, хотя это всего лишь предположение с моей стороны). Также это связано с совместимостью с C. Результатом устранения такой экзистенциальной неопределенности из C++ стал C# 😉
Учитывая, что тип char
существует, я считаю, что имеет смысл, чтобы обычные потоки использовали его, даже несмотря на то, что его знаковость не определена. Таким образом, возможно, на ваш вопрос можно ответить, ссылаясь на вопрос: "Почему C++ просто не определил char
как unsigned
?"
char
предназначен для символов, unsigned char
— для необработанных байтов данных, а signed char
— для знаковых данных.
Стандарт не указывает, будет ли char
реализован как знаковый или беззнаковый тип — это зависит от компилятора. Он лишь указывает, что char
будет "достаточно" велик, чтобы держать символы на вашей системе — в те времена это были не Юникод.
Использование char
для представления символов — это стандартный подход. Использование unsigned char
считается неким "хаком", хотя на большинстве платформ он будет соответствовать реализации char
компилятора.
Почему чтение строк из stdin в C++ гораздо медленнее, чем в Python?
Самый быстрый способ проверить существование файла с использованием стандартного C++/C++11, C++14, C++17/C?
"std::endl" против "\n": в чем разница?"
Что такое Правило трёх?
Разница между const int*, const int * const и int * const?