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;
}
  1. A*b ist eine Ganzzahl, und beim Herausziehen aus der Schleife würde die Genauigkeit des Werts sinken
  2. Ba und b könnten auf dieselbe Stelle zeigen, und *b könnte sich durch das Schreiben nach a[i] ändern
  3. 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.

Dieses Thema üben Zur Themenseite

Weitere Fragen zu Compiler

  1. Welche Kombination dessen, was Knoten und Kanten darstellen, ist richtig, wenn bei der Registerzuteilung des Compilers das Verfahren der Färbung des Interferenzgraphen verwendet wird?
  2. Was geschieht mit dem erzeugten Code, wenn bei der Registerzuteilung ein „Spill“ auftritt?
  3. Was ist das Hauptziel der Befehlsplanung (Instruction Scheduling) des Compilers?
  4. Welche Wirkung hat es, wenn auf den letzten rekursiven Aufruf der obigen Funktion die Tail-Call-Optimierung angewendet wird?
  5. Welche Aussage zum Unterschied zwischen Compiler und Interpreter ist richtig?

Vergleiche zu diesem Thema