2015-07-22 13 views
20

Tôi tự hỏi nếu điều này mang lại trong hành vi undefined:Đang gọi printf với các đối số dư thừa hành vi không xác định?

printf("Test %d %s", 123, "abc", "def", "ghi"); 

Hai đối số đầu tiên sau chuỗi định dạng phù hợp với chuỗi định dạng, vì vậy đây là những OK; nhưng các đối số thứ 3 và thứ 4 bị vượt quá vì không có thêm các định dạng tương ứng.

IMHO printf() chỉ đơn giản là bỏ qua các đối số dư thừa này và không nên có UB. Điều này có đúng không?

+0

Tôi nghĩ rằng câu hỏi này giống như hỏi "Có thể một hàm chấp nhận varargs có bất kỳ số đối số nào không?". Cơ chế cho phép xử lý một số biến đối số hoạt động bất kể những gì cụ thể về cách hàm sử dụng các đối số đó ... – SJuan76

Trả lời

32

Có, kịch bản này được xác định rõ ràng theo tiêu chuẩn. Đó là không phải hành vi không xác định.

Để trích dẫn tiêu chuẩn C11, chương §7.21.6.1, Các fprintf() chức năng

[...] Nếu định dạng được sử dụng hết trong khi tranh luận vẫn còn, các đối số dư được đánh giá (như luôn) nhưng nếu không thì bỏ qua [...]

+3

+1, tôi không biết rằng nó được xác định rõ ràng. BTW "không UB" có thể được tối ưu hóa, "không" và "bỏ" hủy bỏ, vẫn còn "hành vi được xác định". –

+0

Là một người không quen với việc triển khai C: tại sao lại đánh giá các đối số còn sót lại? Giả sử chuỗi định dạng gốc (đối số đầu tiên) được đánh giá trước khi thay thế, điều này có vẻ như nó có thể được tối ưu hóa. – Jules

+3

@JulesMazur Không đánh giá các đối số có nghĩa là 'printf ("% d ", ++ i);' sẽ tăng 'i', trong khi' printf ("foo", ++ i); 'thì không. Mà hầu như không làm cho bất kỳ ý nghĩa và vô cùng mơ hồ. Do đó, "như thường lệ", các đối số được đánh giá trước khi được truyền vào, sau đó bị bỏ qua bởi hàm. – Quentin

3

về cơ bản, printf (hoặc bất kỳ chức năng định dạng) sẽ xem xét chỉ 'n' số% d,% c% f. .., vv trong chuỗi định dạng từ đối số danh sách biến. Những người khác chỉ đơn giản là bỏ qua.

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