Seite 1 von 1

UB Falle mit Compound Literal

Verfasst: 18.01.2026, 17:22
von starcow
Ich bin heute wohl fast in eine (wie ich finde, richtig fiese) UB Falle gelaufen.
Jedenfalls scheint es tatsächlich UB zu sein, soweit ich es bis jetzt recherchieren konnte.

Grundidee: Wird als Funktions-Argument ein Null-Pointer übergeben, soll dieser auf einen gültigen Stack-Bereich gebogen werden.
Somit kann nach einmaligem Prüfen normal mit dem Pointer gearbeitet werden.
Da dieser temporäre Stack-Bereich sowieso nur über diesen Pointer erreichbar sein soll, würde sich ein Compound Literal geradezu anbieten (abgesehen von gnu C++ extensions nur in C).

Code: Alles auswählen

if(!p_opt_output)
    p_opt_output = &(struct foo){ 0 };
Soweit klar: Ein Compound Literal, das innerhalb einer Funktion steht, hat automatic storage duration und Block Scope.
Also alles gut - genauso, wie man es haben will.

Leider nein, denn ein if statement bildet immer einen eigenen Block und damit einen eigenen Block Skope, dessen Ende direkt hinter dem if-statement liegt. Unabhängig davon, ob {} verwendet wird.
Das Compound Literal wird also nach dem if statement ungültig und der Zugriff per Pointer UB.
Mit

Code: Alles auswählen

if(!p_opt_output)
{
    p_opt_output = &(struct foo){ 0 };
}
wäre es gleichermassen UB - doch würde man hier wohl eher auf den Trichter kommen.

Soweit ich das bis jetzt recherchieren konnte, ist das mittels Ternary Operator tatsächlich anders und wohldefiniert.

Code: Alles auswählen

p_opt_output = p_opt_output ? p_opt_output : &(struct foo){ 0 };
Edit:
Ich habe die Beispiele etwas angepasst. Mit einem pointer to struct ist es wohl näher an der Realität.

Re: UB Falle mit Compound Literal

Verfasst: 18.01.2026, 20:42
von Krishty
Nette Falle; die versteckt sich auch in einigen Beispielen der Microsoft-Docs …

Wie wurdest du auf den Fehler aufmerksam? Valgrind? Address Sanitizer?