2017-07-04 1 views
-2

Ich versuche zu verstehen, was mit meinem Wissen über C-Programmierung passiert ist. Beginnen wir mit einem KLASSISCHEN Problem (Dereferenzierung nicht initialisierter Zeiger):Warum Clang Dereferenzierung nicht initialisierter Zeiger unterstützt

int main(void) { 
    char *p; 
    *p = 'a'; 
    printf("%c\n", *p); 
    return 0; 
} 

Dies ist offensichtlich falsch! Ich weiß es. Als ich dies jedoch auf meinem MacOS 10.12 mit LLVM Clang 8.1.0 als Compiler ausgeführt habe, konnte es nicht nur nicht initialisierte Pointer erkennen, sondern auch das Zeichen 'a' auf dem Bildschirm anzeigen, als ob nichts falsch wäre. Zumindest erwarte ich etwas wie "Segmentation Fault".

Bitte halten Sie Ihre Gedanken und Bär mit mir einen Moment den folgenden Code ein, um zu sehen:

int main(void) { 
    int i; 
    char **strPtr; 
    char *string = "Hello, world!"; 

    *strPtr = string; 

    printf("%s", *strPtr); 
    return 0; 
} 

Dieses Mal lief ich den Code mit GCC-4.8.5, die erfolgreich die Segmentierungsfehler in der ersten erkannt hat Code. Zu meiner Bestürzung, die Zeichenfolge "Hallo, Welt!" erschien auf dem Bildschirm, nachdem ich den Code ausgeführt habe, als ob nichts damit falsch war.

Ich frage mich, da StrPtr ist auch ein Zeiger (obwohl ein Zeiger auf Zeiger), durch Dereferenzierung und Zuweisung von Wert zu StrPtr, sollte ich nicht den gleichen Fehler wie ich im ersten Code begangen?

+2

Erzähle, dass du dich vor solchen Dingen warnen sollst ('-Wall'), und dass es solche Warnfehler (' -Werror') berücksichtigen sollte. Mit anderen Worten, z.B. 'clang -Wall -Werror source.c -o binary'. –

+0

Ihr Zeiger ist nicht nicht initialisiert. Und jeder Gott-Compiler, einschließlich Clang wird vor einer unsinnigen Konvertierung warnen. Es ist nicht der Fehler des Compilers, wenn Sie sie ignorieren (oder die empfohlenen Warnungen nicht aktivieren) – Olaf

+0

"aber auch das Ergebnis angezeigt" - welches Ergebnis? Dieser Code macht keinen Sinn, ruft aber undefiniertes Verhalten auf. – Olaf

Antwort

3

Es ist nicht Unterstützung es; Es ist nur so, dass der Compiler davon ausgeht, dass Sie wissen, was Sie tun.

Es ist nur, dass das Verhalten bei der Dereferenzierung eines nichtinitialisierten Zeigers undefined ist.

Es scheint zu funktionieren, ist eine Manifestation dieses undefinierten Verhaltens.

Erinnern Sie sich an die alte Maxime: C gibt Ihnen die Möglichkeit, sich in den Fuß zu schießen.

Verwandte Themen