Search code examples
c++chartype-conversionbyteuint8t

Char to int8_t conversion gives unexpected results?


Why casting char to int8_t keeps giving me the alphabetical (char) representation rather than numerical value?

Casting char to int16_t or int gives me expected numerical value.

char a = 'x';
std::cout << "Casting '" << a << "' (char) to (int8_t): " << (int8_t)a << '\n';
std::cout << "Casting '" << a << "' (char) to (int16_t): " << (int16_t)a << '\n';

unsigned char b = 'y';
std::cout << "Casting '" << b << "' (uchar) to (uint8_t): " << (uint8_t)b << '\n';
std::cout << "Casting '" << b << "' (uchar) to (uint16_t): " << (uint16_t)b << '\n';

// Further example:
int8_t c = 'z';
int16_t d = 'z';
int e = 'z';
std::cout << c << '\n' << d << '\n' << e << '\n';

Outputs:

Casting 'x' (char) to (int8_t): x
Casting 'x' (char) to (int16_t): 120
Casting 'y' (uchar) to (uint8_t): y
Casting 'y' (uchar) to (uint16_t): 121
z
122
122

My side goal is to read the file of characters into an array whose each each element is represented as 0..255 value (without any further casting).

My solution works fine:

auto buffer = std::make_unique<unsigned char[]>(file_length); // <uint8_t> also works
file.read(reinterpret_cast<char*>(buffer.get()), file_length);

for (int i = 0; i < file_length; i++) {
        std::cout << std::dec << (uint16_t)buffer[i] << std::endl;
}

However it still requires casting to uint16_t and interpreting as decimal, in order to print the result as a 0..255 number.

An alternative would be to simply use uint16_t as a type of an array, that way there would be no further casting other than interpreting as decimal, however I am still curious why uint8_t won't work.

Thanks.


Solution

  • The optional type int8_t does not have to exist, but when it does, it's very often an alias for char (or signed char) and is therefor picked up by

    std::ostream& operator<<(std::ostream&, char);

    when you stream it, which, as you've noticed, outputs the character and not its numeric value.

    So, to output an int8_t's (or char's) numeric value, you need to cast:

    std::cout << static_cast<int>(variable);