Этот вопрос относится к добавлению 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
происходит; или может ли решение "путешествие во времени".
Та же проблема может возникнуть для программы, которая считывает двоичный двоичный объект в буфер, а затем принимает решение во время выполнения о том, как получить к нему доступ (например, десериализация; заголовок сообщает нам, будет ли всплывать float или int).