Diese Frage bezieht sich auf die Hinzufügung von P0593 zum neuesten C ++ 20-Entwurf .
Hier ist mein Beispiel:
#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]
}
Ist dieser Code für alle Eingaben im neuesten Entwurf genau definiert?
Die in P0593 zum Ausdruck gebrachte Begründung macht ziemlich deutlich, dass das Auskommentieren [2]
aufgrund einer strengen Aliasing-Verletzung zu undefiniertem Verhalten führen würde, wenn sich die beiden Benutzereingabeelemente unterscheiden. Die implizite Objekterstellung soll nur einmal an dem Punkt erfolgen malloc
; Es wird nicht durch die Zuweisungsanweisung in ausgelöst foo
.
Für jede tatsächliche Ausführung des Programms gibt es ein Mitglied der nicht angegebenen Menge impliziter Objekte, die das Programm klar definieren würden. Mir ist jedoch nicht klar, ob die in [intro.object] / 10 erwähnte Wahl der impliziten Objekterstellung getroffen werden muss, wenn malloc
dies geschieht. oder ob die Entscheidung "Zeitreise" kann.
Das gleiche Problem kann bei einem Programm auftreten, das einen binären Blob in einen Puffer liest und dann zur Laufzeit entscheidet, wie darauf zugegriffen werden soll (z. B. Deserialisierung; und der Header gibt an, ob ein Float oder ein Int ansteht).