To pytanie dotyczy dodania P0593 do najnowszej wersji C ++ 20 .
Oto mój przykład:
#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]
}
Czy ten kod jest dobrze zdefiniowany dla wszystkich danych wejściowych w najnowszej wersji roboczej?
Uzasadnienie wyrażone w P0593 wyjaśnia dość wyraźnie, że odkomentowanie [2]
prowadziłoby do nieokreślonego zachowania z powodu ścisłego naruszenia aliasingu, jeśli dwa elementy wprowadzone przez użytkownika różnią się. Domniemane stworzenie obiektu powinno nastąpić tylko raz, w punkcie malloc
; nie jest wywoływane przez instrukcję przypisania w foo
.
Dla każdego faktycznego uruchomienia programu istnieje element nieokreślonego zestawu niejawnych obiektów, który sprawiłby, że program byłby dobrze zdefiniowany. Ale nie jest dla mnie jasne, czy wybór tworzenia niejawnego obiektu, o którym mowa w [intro.object] / 10, musi być dokonany, kiedy to malloc
nastąpi; lub czy decyzja może dotyczyć „podróży w czasie”.
Ten sam problem może pojawić się w przypadku programu, który odczytuje binarny obiekt blob do bufora, a następnie podejmuje w czasie wykonywania decyzję, w jaki sposób uzyskać do niego dostęp (np. Deserializacja; a nagłówek mówi nam, czy nadchodzi liczba zmiennoprzecinkowa czy int).