Учитывая следующий код.
#include <cstdint>
#include <iostream>
#include <limits>
int main()
{
int8_t x = 5;
std::cout << x << '\n';
int y = 5;
std::cout << y;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
Мой вывод трехлистный клевер а также 5. Если целые числа фиксированной ширины являются целыми числами, почему они выводят символьный символ ASCII своего числа?
Редактировать: только что обнаружил, что такое поведение происходит только для 8-битных целых чисел фиксированной ширины? Это поведение компилятора?
Ну, они являются целыми числами в том смысле, что вы можете делать с ними 8-битную целочисленную арифметику.
Но, видимо, в вашей системе, int8_t
реализован в виде typedef
в signed char
, Это абсолютно законно, так как signed char
s также являются целыми числами, но дает неожиданные результаты, так как operator<<
за signed char
s печатает их символьный символ, а не числовое значение. Что-нибудь еще было бы странно, если бы кто-то попытался напечатать signed char
,
Если вы хотите увидеть числовое значение вашего int8_t
просто приведите к int
перед печатью.
(Необязательные) типы фиксированной ширины intN_t
а также различные другие типы, такие как uint_fast16_t
, uintmax_t
а также intptr_t
, являются псевдонимы для одного из встроенных интегральных типов. Вы не знаете, что на самом деле представляют собой псевдонимы, только то, что они должны соответствовать задокументированным ограничениям.
В случае «ровно 8 бит» ограничения не оставляют много места, и единственными целочисленными типами, которые могут быть шириной 8 бит, являются char
типы (напомним, их три). Так int8_t
, если он существует, должен быть псевдоним для любого char
или же signed char
,
Вне зависимости iostreams определяет перегрузки для operator<<
для всех типов символов, которые имеют эффект записи значения непосредственно в вывод, а не форматирования целого числа в виде десятичной строки (это так, чтобы вы могли удобно написать std::cout << 'a'
), и эта перегрузка также используется для int8_t
— разрешение перегрузки работает с типами, а не с именами типов. (Возможно, прискорбно, что есть специальная перегрузка ostream для signed char
; это могло бы быть лучше только обеспечить перегрузку для char
и относитесь к другим типам как к обычным целым числам.) Вот почему вы видите значение, напечатанное как символ в кодировке вашей системы.
Если вы хотите напечатать значение, отформатированное в виде строки, просто преобразуйте его в один из более широких целочисленных типов. Например, вы можете применить стандартные акции с унарным плюсом: int8_t x = 5; std::cout << +x;