2010-06-11 25 views
16

Tôi đã hàm sau để đọc một quadword lớn về cuối nhỏ (trong một tập tin cơ sở trừu tượng I/O lớp):Phím Shift đếm số âm hoặc lỗi quá lớn - giải pháp đúng?

unsigned long long File::readBigEndQuadWord(){ 
    unsigned long long qT = 0; 
    qT |= readb() << 56; 
    qT |= readb() << 48; 
    qT |= readb() << 40; 
    qT |= readb() << 32; 
    qT |= readb() << 24; 
    qT |= readb() << 16; 
    qT |= readb() << 8; 
    qT |= readb() << 0; 
    return qT; 
} 

Các readb() chức năng đọc một BYTE. Sau đây là các typedefs sử dụng:

typedef unsigned char BYTE; 
typedef unsigned short WORD; 
typedef unsigned long DWORD; 

Cái này là tôi nhận được 4 cảnh báo trình biên dịch trên bốn dòng đầu tiên với việc dịch chuyển này:

cảnh báo C4293: '< <': đếm sự thay đổi tiêu cực hoặc quá lớn, không được xác định hành vi

Tôi hiểu tại sao cảnh báo này xảy ra, nhưng tôi không thể tìm ra cách loại bỏ nó chính xác. Tôi có thể làm điều gì đó như:

qT |= (unsigned long long)readb() << 56;

Điều này sẽ loại bỏ cảnh báo, nhưng không có bất kỳ sự cố nào khác, liệu BYTE có được mở rộng chính xác không? Có lẽ tôi chỉ nghĩ về nó quá nhiều và giải pháp là đơn giản. Các bạn có thể giúp tôi ở đây không? Cảm ơn.

Trả lời

12

Cách xóa cảnh báo của bạn là chính xác. Như bạn có thể đã biết, cảnh báo đang xảy ra vì bạn đang cố gắng chuyển nội dung của một byte vượt quá ranh giới của một từ, sau đó lưu trữ nó trong quadword. Thao tác này không xác định. (Nó sẽ đánh giá phía bên phải của nhiệm vụ trước khi gán giá trị.) Bằng cách đúc một cách rõ ràng trước, bây giờ có đủ không gian để thực hiện ca làm việc, vì vậy không có gì để khiếu nại. Có thể cho rằng, trình biên dịch sẽ có thể tìm ra bạn sẽ lưu trữ nó trong quadword, vì vậy nó nên phân bổ một quadword đầu tiên và thực hiện thay đổi ở đó, nhưng nó có thể chưa được thực hiện đủ thông minh để tìm nó ngoài.

Ngoài ra, tôi không chắc chắn về điều này, nhưng có thể biên dịch này cho x64 cũng sẽ không tạo ra cảnh báo, như một từ là 64 bit?

+0

Cảm ơn câu trả lời của bạn. Bản thân tôi nghĩ rằng trình biên dịch phải đủ thông minh để xem tôi đang gán nó cho một biến đủ lớn để chứa tất cả dữ liệu (tôi đang sử dụng MSVS2008). Nhưng cảnh báo mang lại những nghi ngờ về tính chính xác của mã của tôi, vì vậy tôi hỏi ở đây. – PeterK

+5

Nếu trình biên dịch đã tìm ra những gì bạn đang làm với kết quả và thay đổi các loại trung gian cho phù hợp, sau đó nó sẽ phá vỡ các tiêu chuẩn ngôn ngữ. Loại khuyến mãi được xác định rõ và loại kết quả của toán tử chỉ phụ thuộc vào loại toán hạng. –

+0

Tính đến tháng 3 năm 2015, việc biên dịch mã như vậy với MSVC 2013 vẫn tạo ra cảnh báo. – Yadli

2

qT | = (chưa ký dài lâu) readb() < < (shiftvalue & 63); Điều này sẽ là giải pháp hoàn hảo giả sử u không requiered hơn 63 bit thay đổi

+0

tốt, anh ấy yêu cầu thay đổi 56 bit –

Các vấn đề liên quan