uint8_t iostream behavior

狂风中的少年 提交于 2019-11-27 07:45:13

问题


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);
    }
}

回答1:


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.




回答2:


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.




回答3:


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!