For some testing purpose I want to display int8_t variables, cast them to uint8_t and display them again, in hexadecimal.
#include <iostream>
#include <sstream>
int main()
{
std::int8_t t = -1;
std::cout << std::hex << +t << std::endl;
std::cout << std::hex << +static_cast<std::uint8_t>(t) << std::endl;
return 0;
}
Here is my output for this program:
$ ./a.exe
ffffffff
ff
cout seems to format an int8_t as 4 bytes. Why is that? As it is a one-byte value, one would expect to see ff, like an uint8_t, which is the case in this example.
Why is the output format of an int8_t uses 4 bytes?
It doesn't. You're outputting an int
, not a int8_t
.
To stream a uint8_t
to std::cout
with lexical conversions, you have correctly used +
to trigger a promotion to int
(needed because char
and related types do not undergo lexical conversion with IOstreams).
But then… you've promoted it to int
. So you see int
-like things.
Your second line is good and ensures you don't fall foul of sign extension.
The problem is that you use the unary arithmetic operator +
which performs integer promotion. So your int8_t
is promoted to an integer. Which with your compiler and set up is 32 bits.
The built-in unary plus operator returns the value of its operand. The only situation where it is not a no-op is when the operand has integral type or unscoped enumeration type, which is changed by integral promotion, e.g, it converts
char
toint
or if the operand is subject to lvalue-to-rvalue, array-to-pointer, or function-to-pointer conversion.
Source: https://en.cppreference.com/w/cpp/language/operator_arithmetic
The operand of the unary + operator shall have arithmetic, unscoped enumeration, or pointer type and the result is the value of the argument. Integral promotion is performed on integral or enumeration operands. The type of the result is the type of the promoted operand.
Source C++ Standard § 8.3.1.7
A little addition to the existing answers
auto x1 = static_cast<int8_t>(-1);
// x1 has type int8_t and contains value -1
auto x2 = static_cast<uint8_t>(-1);
// x2 has type uint8_t and contains value 255 !
// uint8_t cant represent value -1
// promotion to int
auto y1 = +x1; // y1 has type int with value -1
auto y2 = +x2; // y2 has also type int with value 255
std::cout << y1 << "\n"; // output "-1"
std::cout << y2 << "\n"; // output "255"
std::cout << std::hex << y1 << "\n"; // output "ffffffff" for hex representation of -1
std::cout << std::hex << y2 << "\n"; // output "ff" for hex representation of 255
I hope this code snippet makes it l little bit easier to understand.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With