Reputation: 145
I was playing around with C++17 std::byte
, and I came across some weird behaviour.
I don't know if it is intended or not, or if I am doing something wrong.
std::byte test_byte{80};
std::cout << "Test: " << std::to_integer<uint8_t>(test_byte) << " vs " << std::to_integer<uint16_t>(test_byte) << "\n";
This will print out:
Test: P vs 80
I then looked up the ASCII table and found that uppercase P's numerical value is 80.
My question is if this is the intended or if it's a bug, or maybe even OS/Compiler specific?
Running Windows 10 and compiling with VS Build Tools.
Upvotes: 0
Views: 529
Reputation: 7925
Compare these two lines of code:
unsigned char c = 80;
std::cout << c << '\n';
std::cout << +c << '\n';
This should help you to understand what is going on!
In the first case, it will print the ASCII
character or even possibly the UNICODE
character of that value depending on the architect and platform (Hardware Manufacturer: Intel, AMD, etc, and Windows, Mac, Linux, etc.) and the type of stream_buf
that is being used... It may not even print anything and cause your internal computer's buzzer to beep depending on the value...
In the second case, it will print the actual value 80
to the console.
What is happening here is that the unsigned char
is interpreted by the std::basic_streambuf
class different than a conventional integral
signed
or unsigned
type because it is of a char
type. You may or may not see this same effect with a signed char
I'm not 100% sure on that, but I am 100% sure of the unsigned char
type.
The reason the value 80
is printed in the second case is due to the unary
operator+()
being prefixed to the unsigned char
type. This causes integer promotion.
This characteristic or side-effect will carry out for any and all types that are either typedef
or aliased
from unsigned char
.
In your case, you are seeing P
being printed because you are casting or converting to the unsigned char
type since uint8_t
is an unsigned char
!
Upvotes: 1
Reputation: 238441
My question is if this is the intended
Sort of.
if it's a bug
No. It's just a slight inconvenience in the API.
or maybe even OS/Compiler specific?
No.
This has nothing to do with std::to_integer
. The issue is that the integer type that is 8 bits wide on your system happens to be (unsigned
) char
. And this integer type happens to also be a character type.
And integers that are characters are treated differently from integers that aren't character types by character streams. Specifically, the behaviour is to print the character encoded by that integer, rather than textual representation of the value.
The solution is to convert the uint8_t
into a wider integer type such as unsigned int
before inserting it into a character stream.
Upvotes: 3