Compiler
Warum kann der Compiler in der obigen Funktion die Optimierung, das Lesen von *b aus der Schleife herauszuziehen, nicht ohne Weiteres durchführen?
void add(int *a, int *b, int n) {
for (int i = 0; i < n; i++)
a[i] += *b;
}
- A*b ist eine Ganzzahl, und beim Herausziehen aus der Schleife würde die Genauigkeit des Werts sinken
- Ba und b könnten auf dieselbe Stelle zeigen, und *b könnte sich durch das Schreiben nach a[i] ändern
- CFür Funktionen mit Zeigerparametern darf der Compiler laut Regel grundsätzlich nicht optimieren
Antwort und Erläuterung anzeigen
Antwort: B. a und b könnten auf dieselbe Stelle zeigen, und *b könnte sich durch das Schreiben nach a[i] ändern
Auf den ersten Blick ändert sich *b in der Schleife nicht und müsste daher nur einmal gelesen werden. Übergibt die aufrufende Seite jedoch z. B. mit add(x, &x[3], n) einen Zeiger b auf ein Element von a, ändert das Schreiben nach a[3] den Wert von *b. Da der Compiler diese Möglichkeit (Aliasing) nicht ausschließen kann, erzeugt er Code, der jedes Mal neu liest. In C kann man mit restrict an Zeigern zusichern, dass sie auf verschiedene Stellen zeigen, und so die Optimierung ermöglichen. Es liegt weder ein Genauigkeitsproblem vor noch ein Optimierungsverbot.