Це питання стосується доповнення P0593 до останнього проекту C ++ 20 .
Ось мій приклад:
#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]
}
Чи чітко визначений цей код для всіх матеріалів у рамках останньої чернетки?
Обґрунтування, висловлене в P0593, дає чітко зрозуміти, що коментування [2]
може призвести до невизначеної поведінки через суворе порушення псевдоніму, якщо два елементи введення користувача відрізняються. Створення неявного об'єкта, як передбачається, відбудеться лише один раз, у точці malloc
; його не спрацьовує оператор призначення в foo
.
Для будь-якого фактичного запуску програми існує член не визначеного набору неявних об'єктів, який би зробив програму чітко визначеною. Але мені незрозуміло, чи слід робити вибір неявного об'єкта, згаданий у [intro.object] / 10, коли це malloc
відбувається; чи рішення може «подорожувати часом».
Це ж питання може виникнути і для програми, яка читає двійкову крапку в буфер і потім приймає рішення про час доступу до неї (наприклад, дезаріалізація; а заголовок повідомляє, чи з’являється флоат або int).