Compilers
Waarom kan de compiler in de bovenstaande functie de optimalisatie waarbij het lezen van *b buiten de lus wordt gebracht niet zonder meer uitvoeren?
void add(int *a, int *b, int n) {
for (int i = 0; i < n; i++)
a[i] += *b;
}
- A*b is een geheel getal, dus verplaatsing buiten de lus verlaagt de precisie van de waarde
- Ba en b kunnen naar dezelfde plaats wijzen, en door het schrijven naar a[i] kan *b veranderen
- CVoor functies die pointers als argument nemen, is optimaliseren door de compiler volgens de regels helemaal verboden
Antwoord en toelichting tonen
Antwoord: B. a en b kunnen naar dezelfde plaats wijzen, en door het schrijven naar a[i] kan *b veranderen
Op het eerste gezicht verandert *b in de lus niet en lijkt eenmaal lezen voldoende. Als de aanroeper echter een pointer doorgeeft waarbij b naar een element van a wijst, bijvoorbeeld add(x, &x[3], n), verandert de waarde van *b door het schrijven naar a[3]. De compiler kan deze mogelijkheid (aliasing) niet uitsluiten en genereert daarom code die telkens opnieuw leest. In C kan worden geoptimaliseerd door pointers met restrict te markeren en zo te beloven dat ze naar verschillende plaatsen wijzen. Het is geen kwestie van precisie, en optimalisatie is niet verboden.