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.