clang - zwei verschiedene Werte an selber Speicherstelle?



  • Hallo,

    ich teste hier ein paar Eigenschaften von C. Mit gcc kompiliert gibt er mir zweimal "d" aus, während mit clang trotz gleicher Speicherstelle zwei verschiedene Werte ausgegeben werden...
    Liegt das nur an meinem System/clang Version oder ist das korrekt bzw ein Fehler von clang?

    #include <stdio.h>
    int main(void)
    {	
    	const char c = 'c';
    	char *d;
    	d = (char *)&c;
    	*d = 'd';
    	printf("d: %p\n", d);	
    	printf("d: %c\n", *d);
    	printf("c: %p\n", &c);
    	printf("c: %c\n", c);
    	return 0;
    } /* main */
    

    $ gcc -std=c99 -Wextra -ggdb -O0 -o const1 const1.c
    $ const1
    d: 0x7fff99510d57
    d: d
    c: 0x7fff99510d57
    c: d
    $ clang -std=c99 -Wextra -ggdb -O0 -o const1 const1.c
    $ const1
    d: 0x7fff89661e4b
    d: d
    c: 0x7fff89661e4b
    c: c

    Gruß
    rifkin



  • Wenn ich mich recht erinnere, darfst Du const nur wegcasten, wenn das Objekt ursprünglich gar nicht const war.
    Da Du geschummelt hast, darf der Compiler zurückschummeln.



  • morgens 5 Uhr in Deutschland 🙂
    also der debugger meint was anderes als die Ausgabe. Also zweimal den Wert 'd' wie erwartet. Kannst du das replizieren?



  • Der Compiler darf annehmen, dass c sich nicht verändert, weil es als konstant definiert wurde. Ich vermute, dass clang c in ein Register packt und den Stack für die Auswertung von c später gar nicht heranzieht. Zwar muss er dort auch ein 'c' ablegen, weil du &c verlangst, aber da c sich nicht ändern kann, hat er keine Verpflichtung, es später wieder von da zu lesen.

    Übrigens erzeugt

    d = (char *)&c;
        *d = 'd';
    

    ganz klar undefiniertes Verhalten. Wenn clang da ein Programm erzeugt, das deine Festplatte 35 mal mit Nullen überschreibt, ist das immer noch standardkonform.



  • Vor dem letzten printf() schreibt er tatsächlich 0x63 ('c') hard-coded in esi.

    mov    esi,0x63
    mov    DWORD PTR [rbp-0x1c],eax
    call   0x4004c0 <printf@plt>
    

    Hatte mehrere Compiler ausprobiert. Macht nur clang.


  • Mod

    rifkin schrieb:

    Hatte mehrere Compiler ausprobiert. Macht nur clang.

    1. Der Compiler hat recht. Es liegt an deinem Programm.
    2. Das Verhalten lässt ebenso mit gcc vor 4.5 (getestet mit 4.3.6.,4.0.2,4.1.2,4.2.4,4.3.6,4.4.7) reproduzieren, sofern wenigstens minimal (-O1) optimiert wird. Möglich das sich das auch mit neueren Version demonstrieren lässt - ich schätze mal, dass das auch von der Zielplattform abhängen wird, je nachdem, welche Variante besseren Code erzeugt.



  • volkard schrieb:

    Da Du geschummelt hast, darf der Compiler zurückschummeln.

    😃


Anmelden zum Antworten