2013-03-08 2 views
9

Abstract: Mi aspettavo il codice: cout < < uint8_t (0); per stampare "0", ma non stampa nulla.uint8_t comportamento iostream

Versione lunga: quando provo a eseguire lo streaming di oggetti uint8_t su cout, ottengo strani caratteri con gcc. È questo comportamento previsto? Potrebbe essere che uint8_t è un alias per un tipo basato su char? Vedi le note del compilatore/sistema nell'esempio di codice.

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

risposta

9

uint8_t è un alias per unsigned char, e le iostreams hanno sovraccarichi speciali per i caratteri che stampano i personaggi piuttosto che la formattazione dei numeri.

La conversione in intero lo inibisce.

5

Potrebbe essere che uint8_t è un alias per un tipo basato su char?

Assolutamente. È necessario che sia un typedef per un tipo integrale senza segno incorporato a 8 bit, se tale tipo esiste. Dal momento che ci sono solo due possibili tipi interi senza segno a 8 bit, char per un compilatore che lo tratta come non firmato e unsigned char, deve essere uno di quelli. Tranne sui sistemi in cui char è più grande di 8 bit, nel qual caso non esiste.

+0

+1 per aver ricordato che uint8_t non può esistere! Non lo sapevo. – Johann

+0

@Johann - per la maggior parte degli usi, 'uint_least8_t' è una scelta migliore di' uint8_t'. –

+2

Un'implementazione può fornire tipi di interi più estesi che non sono alias per i tipi di interi standard. Quindi penso che tecnicamente 'uint8_t' * potrebbe * essere un tipo non di caratteri, sebbene di solito non lo sia. – aschepler

0

Come altri hanno sottolineato, uint8_t viene trasmesso in streaming come unsigned char. A volte ho utilizzato campi di bit da tipi interi che sono in streaming come, beh, interi, per evitare di dover eseguire il cast o sovraccaricare operator<<, ma solo quando non spreca spazio, come nella struttura Pos sottostante:

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

uscita:

0 
2 
2