Câu hỏi này đề cập đến việc bổ sung P0593 vào dự thảo C ++ 20 mới nhất .
Đây là ví dụ của tôi:
#include <cstdlib>
#include <cstdio>
void foo(void *p)
{
if ( std::getchar() == 'i' )
{
*(int *)p = 2;
std::printf("%d\n", *(int *)p);
}
else
{
*(float *)p = 2;
std::printf("%f\n", *(float *)p);
}
}
int main()
{
void *a = std::malloc( sizeof(int) + sizeof(float) );
if ( !a ) return EXIT_FAILURE;
foo(a);
// foo(a); [2]
}
Mã này có được xác định rõ cho tất cả các đầu vào theo dự thảo mới nhất không?
Lý do được trình bày trong P0593 cho thấy khá rõ rằng việc không ghi chú [2]
sẽ dẫn đến hành vi không xác định do vi phạm bí danh nghiêm ngặt, nếu hai mục nhập của người dùng khác nhau. Việc tạo đối tượng ngầm được cho là xảy ra chỉ một lần, tại điểm malloc
; nó không được kích hoạt bởi câu lệnh gán trong foo
.
Đối với bất kỳ hoạt động thực tế nào của chương trình, tồn tại một thành viên của tập hợp các đối tượng ẩn không xác định sẽ làm cho chương trình được xác định rõ. Nhưng tôi không rõ liệu lựa chọn tạo đối tượng ngầm được đề cập trong [intro.object] / 10 phải được thực hiện khi malloc
xảy ra hay không; hoặc liệu quyết định có thể "du hành thời gian".
Vấn đề tương tự có thể phát sinh đối với một chương trình đọc một blob nhị phân vào bộ đệm và sau đó đưa ra quyết định về thời gian chạy về cách truy cập nó (ví dụ như khử lưu huỳnh; và tiêu đề cho chúng ta biết liệu float hay int sắp xuất hiện).