Was gibt dieser Code auf dem Bildschirm aus?



  • #include <iostream>
    using namespace std;
    
    int main() 
    {
        string s = "hallo";
        const char *a = s.c_str();
        volatile const char *b = s.c_str();
    
        cout << a << endl;
        cout << b << endl;
    
        puts(a);
        puts((const char*)b); // compiled nicht ohne volatile wegzucasten
    
        printf ("%s\n", a);
        printf ("%s\n", b);
    }
    

    6 Zeilen, in denen "hallo" steht, oder? ­čśë



  • Hm, das h├Ątt ich jetzt auch nicht gedacht.
    Warum wohl?



  • dieNull schrieb:

    Hm, das h├Ątt ich jetzt auch nicht gedacht.
    Warum wohl?

    Ist mir auch ein R├Ątsel. Aber bestimmt kennt jemand die Antwort.



  • Ah, habs raus. Google is your friend ­čśŤ

    void f(const char* ) {}
    
    int main(){
        volatile const char s[] = "hello";
        f(s);
    }
    
    candidate function not viable: no known conversion from 'const volatile char [6]' to 'const char *' for 1st argument
    void f(const char* ) {}
         ^
    

    Und da es bei operator<< des cout's wohl mehrere ├ťberladungen gibt, nimmt er wohl die von bool. Genauso wie wenn man versucht einen Funktionspointer ohne ins void* zu casten auszugeben. Gibt dir auch ne Eins aus.

    Was ich jedoch nicht verstehe, ist warum folgendes jedoch valide ist:

    volatile int x = 10;
    int y = x;
    


  • Wenn man schreibt:

    cout << *b << endl;
    

    kommt ein 'h', wie zu erwarten.
    Aber

    cout << b << endl;
    

    haut nicht hin. Und das h├Ąngt mit volatile zusammen. ­čś×



  • dieNull schrieb:

    Und da es bei operator<< des cout's wohl mehrere ├ťberladungen gibt, nimmt er wohl die von bool.

    Danke, das wird die Erkl├Ąrung sein. Bei ...

    volatile const char *b = 0;
        cout << b << endl;
    

    ... gibt er 0 aus. Er dereferenziert den Pointer also nicht, was crashen w├╝rde.

    Aber irref├╝hrend ist das ganze irgendwie schon. Dem operator<< m├╝sste eine ├ťberladung f├╝r "volatile char*" spendiert werden. Seltsam, dass das vergessen wurde.



  • dieNull schrieb:

    Was ich jedoch nicht verstehe, ist warum folgendes jedoch valide ist:

    volatile int x = 10;
    int y = x;
    

    y wird mit dem Wert initialisiert, der sich gerade in x befindet. Warum sollte das nicht gehen?



  • Andromeda schrieb:

    y wird mit dem Wert initialisiert, der sich gerade in x befindet. Warum sollte das nicht gehen?

    Na

    volatile const char s[] = "hello";
        const char* p = s;
    

    kompiliert nicht, w├Ąhrend das Beispiel von vorhin halt kompiliert.

    Und mit

    volatile int* x = nullptr;
        int* y = x;
    

    das selbe, klappt nicht.

    Also bezieht sich das mit dem "geht nicht" wohl nur auf Pointer.



  • Beachte, wo volatile bei der Zeigerdefinition steht. Hier ist nicht der Zeiger selbst volatile, sondern der Wert, worauf er zeigt, kann fl├╝chtig sein. Weist du ihn einem anderen Zeiger ohne volatile zu, geht der Compiler beim zugreifen ├╝ber diesen davon aus, dass das Ziel nicht fl├╝chtig ist. volatile ist ein Qualifizierer wie const , der kann nicht einfach implizit weggecastet werden.
    Folgendes ginge:

    char *volatile p = ... //der Zeiger selbst ist volatile, nicht das, worauf er zeigt.
    char *a = p;
    


  • volatile int vi = 42;
    int i = vi;
    

    dasselbe mit zeigern:

    int* volatile vpi = ...;
    int* pi = vpi;
    


  • Ahhh.
    Gerafft, danke.


Log in to reply