Đây là một trong những trường hợp kỳ lạ khi chúng tôi phải tuân theo những hạn chế của ngôn ngữ tiếng Anh và cấu trúc không nhất quán trong tiêu chuẩn. Vì vậy, tốt nhất, tôi có thể đưa ra một lập luận phản bác thuyết phục, vì không thể chứng minh được điều đó :) 1
Mã trong câu hỏi thể hiện hành vi được xác định rõ ràng.
Vì [7.1.4] là cơ sở của câu hỏi, hãy bắt đầu ở đó:
Mỗi phòng trong số báo cáo sau đây áp dụng trừ khi quy định rõ ràng trong các mô tả chi tiết tiếp theo: Nếu một đối số cho một hàm có giá trị không hợp lệ ( chẳng hạn như một giá trị bên ngoài lĩnh vực chức năng, hoặc một con trỏ ra ngoài không gian địa chỉ của chương trình, hoặc một con trỏ null , [... ví dụ khác ...] ) [...] hành vi là không xác định. [... các câu khác ...]
Đây là ngôn ngữ vụng về. Một cách hiểu là các mục trong danh sách là UB cho tất cả các chức năng của thư viện, trừ khi bị ghi đè bởi các mô tả riêng lẻ. Nhưng danh sách bắt đầu bằng "chẳng hạn như", cho thấy rằng nó mang tính minh họa, không đầy đủ. Ví dụ, nó không đề cập đến kết thúc null đúng của chuỗi (quan trọng đối với hành vi của ví dụ strcpy
).
Vì vậy, rõ ràng mục đích / phạm vi của 7.1.4 chỉ đơn giản là "giá trị không hợp lệ" dẫn đến UB ( trừ khi có quy định khác ). Chúng ta phải xem xét mô tả của từng hàm để xác định những gì được coi là "giá trị không hợp lệ".
Ví dụ 1 - strcpy
[7.21.2.3] chỉ nói điều này:
Các strcpy
bản sao chức năng chuỗi trỏ đến bởi s2
(bao gồm các ký tự null chấm dứt) vào mảng trỏ đến bởi s1
. Nếu việc sao chép diễn ra giữa các đối tượng chồng lên nhau, hành vi đó là không xác định.
Nó không đề cập rõ ràng đến con trỏ null, nhưng nó cũng không đề cập đến dấu chấm dứt null. Thay vào đó, một suy luận từ "chuỗi được trỏ tới s2
" rằng các giá trị hợp lệ duy nhất là chuỗi (tức là con trỏ đến mảng ký tự kết thúc bằng null).
Thật vậy, mô hình này có thể được nhìn thấy trong các mô tả riêng lẻ. Một số ví dụ khác:
[7.6.4.1 (fenv)] lưu trữ các môi trường nổi-điểm hiện tại trong đối tượng được trỏ đến bởienvp
[7.12.6.4 (frexp)] lưu trữ các số nguyên trong int tượng được trỏ đến bởiexp
[7.19.5.1 (fclose)] các dòng chỉ vào bởistream
Ví dụ 2 - printf
[7.19.6.1] nói điều này về %p
:
p
- Đối số sẽ là một con trỏ tới void
. Giá trị của con trỏ được chuyển đổi thành một chuỗi các ký tự in, theo cách thức được triển khai xác định.
Null là một giá trị con trỏ hợp lệ và phần này không đề cập rõ ràng rằng null là một trường hợp đặc biệt, cũng không phải con trỏ phải trỏ vào một đối tượng. Vì vậy, nó được xác định hành vi.
1. Trừ khi một tác giả tiêu chuẩn đưa ra, hoặc trừ khi chúng tôi có thể tìm thấy điều gì đó tương tự như một tài liệu cơ sở làm rõ mọi thứ.