Abstract: I was expecting the code: cout << uint8_t(0); to print "0", but it doesn't print anything.
Long version: When I try to stream uint8_t objects to cout, I get strange characters with gcc. Is this expected behavior? Could it be that uint8_t is an alias for some char-based type? See compiler/system notes in the code example.
// compile and run with:
// g++ test-uint8.cpp -std=c++11 && ./a.out
// -std=c++0x (for older gcc versions)
/**
* prints out the following with compiler:
* gcc (GCC) 4.7.2 20120921 (Red Hat 4.7.2-2)
* on the system:
* Linux 3.7.9-101.fc17.x86_64
* Note that the first print statement uses an unset uint8_t
* and therefore the behaviour is undefined. (Included here for
* completeness)
> g++ test-uint8.cpp -std=c++11 && ./a.out
>>>�<<< >>>194<<<
>>><<< >>>0<<<
>>><<< >>>0<<<
>>><<< >>>0<<<
>>><<< >>>1<<<
>>><<< >>>2<<<
*
**/
#include <cstdint>
#include <iostream>
void print(const uint8_t& n)
{
std::cout << ">>>" << n << "<<< "
<< ">>>" << (unsigned int)(n) << "<<<\n";
}
int main()
{
uint8_t a;
uint8_t b(0);
uint8_t c = 0;
uint8_t d{0};
uint8_t e = 1;
uint8_t f = 2;
for (auto i : {a,b,c,d,e,f})
{
print(i);
}
}
uint8_t
is an alias for unsigned char
, and the iostreams have special overloads for chars that print out the characters rather than formatting numbers.
The conversion to integer inhibits this.
Could it be that uint8_t is an alias for some char-based type?
Absolutely. It's required to be a typedef for a builtin 8-bit unsigned integral type, if such a type exists. Since there are only two possible 8-bit unsigned integral types, char
for a compiler that treats it as unsigned and unsigned char
, it must be one of those. Except on systems where char
is larger than 8 bits, in which case it won't exist.
As others have pointed out, uint8_t
is streamed as an unsigned char
. I've sometimes made use of bit fields from integer types that are streamed as, well, integers, to avoid having to cast or overload operator<<
, but only when it doesn't waste space, like in the Pos struct below:
#include <iostream>
struct WasteAbyte {
unsigned short has_byte_range:8;
};
struct Pos {
unsigned short x:8;
unsigned short y:8;
};
int main() {
WasteAbyte W = {255};
++W.has_byte_range;
std::cout << W.has_byte_range << std::endl;
std::cout << sizeof(WasteAbyte) << std::endl;
std::cout << sizeof(Pos) << std::endl;
return 0;
}
Output:
0
2
2
来源:https://stackoverflow.com/questions/15296661/uint8-t-iostream-behavior