Tôi đang sử dụng uint16_t
làm bộ đếm chuỗi trong giao thức mạng. Bộ đếm này thường kết thúc tốt đẹp như mong đợi. Khi người nhận nhận được một gói, nó sẽ kiểm tra bộ đếm này so với lần truy cập gần đây nhất để xem liệu đó là một gói mới hay một gói tin không đúng thứ tự.Có phát hiện thấy sự bao bọc chưa ký thông qua truyền tới hành vi chưa được xác định đã ký không?
Cần tính đến các yếu tố cần thiết khi so sánh số thứ tự. Vì vậy, ví dụ: nếu số thứ tự cuối cùng là 0x4000
thì số thứ tự từ 0x4001
đến 0xBFFF
là mới hơn và số thứ tự từ 0xC000
đến 0xFFFF
và từ 0x0000
đến 0x3FFF
nhỏ hơn.
Cách tôi đang làm điều này là như sau:
uint16_t last;
uint16_t current;
...
// read in values for last and current
...
if ((int16_t)(current - last) > 0) {
printf("current is newer\n");
} else {
printf("current is older (or same)\n");
}
Bằng cách trừ hai và xử lý kết quả như một int16_t
, tôi có thể dễ dàng nhận thấy đó là lớn hơn và bao nhiêu. Vì vậy, ví dụ nếu số thứ tự hiện tại ít nhất 5 ít hơn số cuối cùng, tức là ((int16_t)(current - last) < -5)
, tôi có thể giả định điều này không phải do sắp xếp lại gói dữ liệu bình thường và thả gói.
Tôi nhận thấy rằng bao bọc đã ký là không xác định, tuy nhiên trong trường hợp này tôi đang xử lý một giá trị chưa ký như đã ký vì lợi ích của việc so sánh. Điều này gọi hành vi không xác định, và nếu như vậy những gì sẽ là một cách tốt hơn để làm loại so sánh?
Miễn là 'INT_MAX' lớn hơn' UINT16_MAX' (đúng trên hầu hết các nền tảng 32 hoặc 64 bit) sẽ không có bất kỳ hành vi không xác định nào, vì số học được thực hiện trên loại được quảng cáo. – EOF
@Quentin: Nhưng nếu 'INT_MAX' lớn hơn' INT16_MAX', toán hạng sẽ được thăng hạng. – EOF
@EOF Và tôi đã trả lời một câu hỏi về điều đó hai ngày trước. Xấu hổ: < – Quentin