2013-03-08 12 views
9

Abstract: Ich habe den Code erwartet: cout < < uint8_t (0); um "0" zu drucken, aber es wird nichts gedruckt.uint8_t iostream verhalten

Lange Version: Wenn ich versuche, Uint8_t Objekte zu streamen, bekomme ich seltsame Zeichen mit gcc. Ist das erwartetes Verhalten? Könnte es sein, dass uint8_t ein Alias ​​für einen char-basierten Typ ist? Siehe Compiler/System Notes im Codebeispiel.

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

Antwort

9

uint8_t ist ein Alias ​​für unsigned char und die iostreams haben spezielle Überlastungen für Zeichen, die eher die Zeichen auszudrucken als der Formatierung von Zahlen.

Die Umwandlung in Ganzzahl verhindert dies.

5

Könnte es sein, dass uint8_t ein Alias ​​für einen char-basierten Typ ist?

Absolut. Es muss ein typedef für einen integrierten vorzeichenlosen 8-Bit-Typ sein, wenn ein solcher Typ existiert. Da es nur zwei mögliche vorzeichenlose 8-Bit-Typen gibt, char für einen Compiler, der es als unsigniert behandelt und unsigned char, muss es einer von denen sein. Außer auf Systemen, wo char größer als 8 Bits ist, in diesem Fall wird es nicht existieren.

+0

+1 für den Hinweis auf, dass uint8_t existiert nicht! Wusste das nicht. – Johann

+0

@Johann - für die meisten Anwendungen ist 'uint_least8_t' eine bessere Wahl als' uint8_t'. –

+2

Eine Implementierung kann erweiterte Integer-Typen bereitstellen, die keine Aliase für die Standard-Integer-Typen sind. Also denke ich technisch 'uint8_t' * * könnte ein Nicht-Charakter-Typ sein, obwohl es normalerweise nicht ist. – aschepler

0

Wie bereits erwähnt, wird uint8_t als unsigned char gestreamt. Ich habe manchmal Bitfelder von Integer-Typen, die sind gestreamt als, na ja, ganze Zahlen, um zu vermeiden, müssen operator<< zu werfen oder überlasten, aber nur, wenn es keinen Platz verschwendet, wie in der Pos-Struktur unten:

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

Ausgang:

0 
2 
2