Các chương trình sau đây đã không xác định:Tại sao gcc -Wformat không cảnh báo về printf% d trên int không dấu? hành vi
#include <stdio.h>
int main(void)
{
unsigned int x = -100; // This is fine, becomes UINT_MAX - 100
printf("%d\n", x); // This is undefined behavior.
return 0;
}
C99 7.19.6.1p8 bang% d hy vọng một cuộc tranh cãi int.
C99 7.19.6.1p9 khẳng định: "Nếu bất kỳ tranh luận không phải là loại chính xác cho các tương ứng đặc điểm kỹ thuật chuyển đổi, hành vi này là không xác định ."
Tuy nhiên, gcc -Wformat
(bao gồm -Wall
) sẽ không khiếu nại về chương trình trên, tại sao? Đây có phải là lỗi hay thiếu sót có chủ ý không?
Từ manpage gcc:
-Wformat
Kiểm tra các cuộc gọi đến và "printf"
"scanf"
, vv, để đảm bảo rằng các đối số cung cấp có các loại phù hợp với chuỗi định dạng xác định, và rằng các chuyển đổi theo quy định tại các định dạng string make sense
C99 6.3.1.3p3 nói chuyển đổi unsigned để ký kết được thực hiện xác định. – jxh
@ user315052: Không có chuyển đổi; biểu diễn của 'x' (một đối tượng' unsigned int') được hiểu như thể nó là kiểu 'int'. –
@KeithThompson: Tôi nghĩ rằng đó là vì C99 7.15.1.1p2, câu cuối cùng, nơi nó làm cho một ngoại lệ cho đã ký/unsigned khi chuyển đổi các loại đối số thông qua vĩ mô 'va_arg'. – jxh