Grundlagen der Programmiersprache C

int get(int *p) {
    int v = *p;
    if (p == NULL)
        return -1;
    return v;
}

Wird die obige Funktion mit gcc und aktivierter Optimierung kompiliert, kann die Prüfung if (p == NULL) entfernt werden. Was ist der Grund dafür?

  1. A*p wird zuvor gelesen, und wäre p NULL, läge dort bereits undefiniertes Verhalten vor; daher darf angenommen werden, dass p nicht NULL ist
  2. BDer Standard legt fest, dass ein Vergleich mit NULL immer falsch ist
  3. CBei der Optimierung gilt die Regel, dass if-Anweisungen, die Funktionsargumente prüfen, Sache des Aufrufers sind und alle entfernt werden dürfen
Antwort und Erläuterung anzeigen

Antwort: A. *p wird zuvor gelesen, und wäre p NULL, läge dort bereits undefiniertes Verhalten vor; daher darf angenommen werden, dass p nicht NULL ist

Ist p NULL, dereferenziert das zuerst ausgeführte int v = *p; einen NULL-Zeiger, und an dieser Stelle liegt bereits undefiniertes Verhalten vor. Der Compiler darf annehmen, dass kein undefiniertes Verhalten auftritt; da *p gelesen werden konnte, schließt er, dass p nicht NULL ist, und entfernt die Prüfung p == NULL samt return -1. Mit gcc 13 auf x86-64 und -O2 wird die Funktion zu Code, der nur *p liest und zurückgibt; mit -O0 bleibt die Prüfung erhalten. Damit die Prüfung sicher wirkt, prüft man p, bevor *p gelesen wird.

Dieses Thema üben Zur Themenseite

Weitere Fragen zu Grundlagen der Programmiersprache C

  1. Was legt der C-Standard über die Größe des Typs int fest?
  2. In Embedded-Programmen wird eine Variable für den Wert eines 32-Bit-Peripherieregisters oft nicht als unsigned int, sondern als uint32_t aus stdint.h deklariert. Was ist der Hauptgrund dafür?
  3. Welche Ausgabe erzeugt der obige Code mit einer Division zweier Ganzzahlen bei der Ausführung?
  4. Welche Ausgabe erzeugt der obige Code mit Präfix- und Postfix-++ bei der Ausführung?
  5. Welche Ausgabe erzeugt der obige Code, in dessen if-Bedingung = steht, bei der Ausführung?