UB Falle mit Compound Literal
Verfasst: 18.01.2026, 17:22
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).
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
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.
Edit:
Ich habe die Beispiele etwas angepasst. Mit einem pointer to struct ist es wohl näher an der Realität.
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 };
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 };
}
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 };
Ich habe die Beispiele etwas angepasst. Mit einem pointer to struct ist es wohl näher an der Realität.