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.
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
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. –
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