Basis van programmeren in C
int get(int *p) {
int v = *p;
if (p == NULL)
return -1;
return v;
}Als de bovenstaande functie met gcc met ingeschakelde optimalisatie wordt gecompileerd, kan de controle if (p == NULL) worden verwijderd. Wat is de reden?
- A*p wordt eerst gelezen, en als p NULL was, zou dat al ongedefinieerd gedrag zijn, dus de compiler mag aannemen dat p niet NULL is
- BDe standaard legt vast dat een vergelijking met NULL altijd onwaar is
- CBij optimalisatie worden if-statements die functieargumenten controleren als verantwoordelijkheid van de aanroeper beschouwd en mogen ze allemaal worden verwijderd
Antwoord en toelichting tonen
Antwoord: A. *p wordt eerst gelezen, en als p NULL was, zou dat al ongedefinieerd gedrag zijn, dus de compiler mag aannemen dat p niet NULL is
Als p NULL is, derefereert int v = *p;, dat eerst wordt uitgevoerd, een NULL-pointer, en is er op dat moment ongedefinieerd gedrag. Omdat de compiler mag aannemen dat ongedefinieerd gedrag niet optreedt, concludeert hij dat p niet NULL is, aangezien *p is gelezen, en verwijdert hij de controle p == NULL en de return -1. Met gcc 13 voor x86-64 en -O2 wordt de functie code die alleen *p leest en teruggeeft, terwijl bij -O0 de controle blijft staan. Controleer p vóór het lezen van *p om de controle zeker te laten werken.