Chuyển uint_64_t sang va_list không chính xác

Jan 05 2021

Tôi đang viết một printfhàm tùy chỉnh và một hàm uint64_tdường như được chuyển không chính xác thành va_list:

Điểm có vấn đề:

printf("Number is %C, and the next one is %C", 0xff00ffb7, 0xffffffff);

Một phần trong printfquá trình triển khai của tôi tạo ra kết quả không chính xác:

format++;
uint64_t num = va_arg(parameters, uint64_t);

Khi gỡ lỗi với gdb, giá trị của numtrở thành 0xffffffffff00ffb7thay vì 0xff00ffb7tôi mong đợi và giá trị tiếp theo %C numtrở thành 0. Đây có phải là một số hành vi tiêu chuẩn mà tôi đang thiếu hay tôi đang làm sai điều gì đó?

Trả lời

4 chux-ReinstateMonica Jan 05 2021 at 02:39

Nếu 0xff00ffb7được định nghĩa là uint64_tcho một hàm khác nhau, hãy truyền nó.

printf("Number is %C", (uint64_t) 0xff00ffb7);

0xff00ffb7, dưới dạng một hằng số nguyên, có kiểu int, unsigned, long, unsigned long, long longhoặc ,: kiểu unsigned long longđầu tiên mà nó "phù hợp". Với 32-bit int/unsigned, 0xff00ffb7có thể sẽ là unsignednguồn gốc gây ra rắc rối của OP.

Phụ thêm uđể một hằng số là tốt ý tưởng để đảm bảo nó là một số loại unsigned.

Thêm Lhoặc LLvào một hằng số không phải là một ý tưởng hay để đảm bảo một hằng số là uint64_t. Hoặc có thể khớp ( LLthường sẽ), nhưng các hậu tố này không đảm bảo loại đó.

Sử dụng UINT64_C(0xff00ffb7)tạo thành một hằng số kiểu uint_least64_tchắc chắn giống như uint64_ttrên các máy có uint64_t.