2013-03-08 30 views
9

Tóm tắt: Tôi đã mong đợi mã: cout < < uint8_t (0); để in "0", nhưng nó không in bất cứ thứ gì.uint8_t iostream behavior

Phiên bản dài: Khi tôi cố gắng phát các đối tượng uint8_t để cout, tôi nhận được các ký tự lạ với gcc. Đây có phải là hành vi mong đợi không? Có thể nào uint8_t là bí danh cho một số loại dựa trên char? Xem các ghi chú của trình biên dịch/hệ thống trong ví dụ mã.

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

Trả lời

9

uint8_t là một bí danh cho unsigned char, và iostreams có quá tải đặc biệt cho chars đó in ra các nhân vật chứ không phải là định dạng số.

Việc chuyển đổi thành số nguyên ngăn cản điều này.

5

Có thể uint8_t là bí danh cho một số loại dựa trên char không?

Tuyệt đối. Nó được yêu cầu là một typedef cho một kiểu tích phân không dấu tích 8-bit, nếu loại đó tồn tại. Vì chỉ có hai loại tích phân không thể tách rời 8 bit, char cho trình biên dịch xử lý nó là unsigned và unsigned char, nó phải là một trong số đó. Ngoại trừ trên các hệ thống trong đó char lớn hơn 8 bit, trong trường hợp đó, nó sẽ không tồn tại.

+0

+1 để chỉ ra rằng uint8_t có thể không tồn tại! Không biết điều đó. – Johann

+0

@Johann - đối với hầu hết các lần sử dụng, 'uint_least8_t' là lựa chọn tốt hơn' uint8_t'. –

+2

Việc triển khai được phép cung cấp nhiều loại số nguyên mở rộng không phải là bí danh cho các loại số nguyên chuẩn. Vì vậy, tôi nghĩ về mặt kỹ thuật 'uint8_t' * có thể * là một loại không phải ký tự, mặc dù thường thì không. – aschepler

0

Khi những người khác đã chỉ ra, uint8_t được phát trực tiếp dưới dạng unsigned char. Đôi khi tôi đã sử dụng các trường bit từ các loại số nguyên mà được truyền trực tiếp thành số operator<<, nhưng chỉ khi không lãng phí dung lượng, như trong cấu trúc Pos bên dưới:

#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