Wunderwaffe "const_cast"



  • Es kompiliert, aber ob es fehlerfrei läuft ist eine andere sache.
    Du entfernst damit das const, doch damit wird der speicherbereich noch
    lange nicht beschreibbar. das _kann_ zu abstürzen führen (muss aber nicht)

    int i = 42;
    const int *pi = &i;
    *const_cast<int *>(pi) = 43;
    

    das geht ohne probleme, da das ziel wirklich beschreibbar ist.

    wenn du strings auf diese art und weise manipulierst, ist das ergebnis
    undefiniert. der kompiler könnte die zeichenkette zwischenspeichern:

    void func(const char *ptr)
    {
        const_cast<char *>(ptr)[2] = 'a';
    }
    int main()
    {
        const char *ptr = "blub";
    
        func(ptr);
    
        cout << ptr;
    }
    

    kommt da jetzt "blub" oder "blab" raus? das ist undefiniert.

    fazit: const_cast kann z.b. bei klassen nützlich sein, aber wenn man
    nicht weiß was man tut kann das probleme geben (wie immer in C++)

    😃



  • helferlein schrieb:

    kommt da jetzt "blub" oder "blab" raus? das ist undefiniert

    das beispiel ist totaler käse. entweder säuft das programm ab oder es kommt blab raus. hat nichts mit dem const zu tun.



  • muhh schrieb:

    helferlein schrieb:

    kommt da jetzt "blub" oder "blab" raus? das ist undefiniert

    das beispiel ist totaler käse. entweder säuft das programm ab oder es kommt blab raus. hat nichts mit dem const zu tun.

    Hat es doch.
    Das Beispiel führt zu UB. Es darf also genauso "blub" rauskommen ohne dass was "absäuft".

    @Stromberg:
    const_cast ist nicht mächtiger als der "gute alte" C-Style-Cast.
    C++ sagt dass es OK ist const wegzucasten, und dann zu dereferenzieren, wenn der Programmierer dafür sorgt, dass das nur passiert, wenn das Objekt "ursprünglich" nicht const ist. d.h. z.B. wenn du was mit "new" angelegt hast ist const_cast kein Problem.
    Wenn du was lokal ohne const angelegt hast, nur halt irgendwohin als const übergeben, und dieses "Irgendwo" castet das const wieder weg: auch OK.
    Wenn du dagegen was lokal (global, statisch) schon als const anlegst, dann ... ist es nichtmehr OK. Genau das führt dann zu UB. Also bleiben lassen.



  • [quote="hustbaer"]

    muhh schrieb:

    helferlein schrieb:

    kommt da jetzt "blub" oder "blab" raus? das ist undefiniert

    das beispiel ist totaler käse. entweder säuft das programm ab oder es kommt blab raus. hat nichts mit dem const zu tun.

    Hat es doch.
    Das Beispiel führt zu UB. Es darf also genauso "blub" rauskommen ohne dass was "absäuft".

    wieder käse. sieh genau hin. wie soll da blub rauskommen? wie muss ich den compiler einstellen damit da blub rauskommt?



  • muhh schrieb:

    wieder käse. sieh genau hin. wie soll da blub rauskommen? wie muss ich den compiler einstellen damit da blub rauskommt?

    Einstellen am Compiler musst du dazu gar nichts, der Compiler darf an der Stelle alles - da undefiniert - machen, Kaffe kochen, die Festplatte formatieren, den konstanten Wert unmodifiziert lassen...

    Wenn statt "const char *" bzw "char const *" ein "char * const" verwendet werden würde, wäre es wohl definiert was passiert.



  • muhh schrieb:

    hustbaer schrieb:

    muhh schrieb:

    helferlein schrieb:

    kommt da jetzt "blub" oder "blab" raus? das ist undefiniert

    das beispiel ist totaler käse. entweder säuft das programm ab oder es kommt blab raus. hat nichts mit dem const zu tun.

    Hat es doch.
    Das Beispiel führt zu UB. Es darf also genauso "blub" rauskommen ohne dass was "absäuft".

    wieder käse. sieh genau hin. wie soll da blub rauskommen? wie muss ich den compiler einstellen damit da blub rauskommt?

    UB = undefined behaviour
    lies im Standard nach, oder gib Ruhe



  • helferlein schrieb:

    wenn du strings auf diese art und weise manipulierst, ist das ergebnis undefiniert. der kompiler könnte die zeichenkette zwischenspeichern:

    Nicht grundsätzlich Strings, sondern Stringliterale, denn die dürfen nicht verändert werden.

    Wie sieht es mit anderen Literalen aus? Kann da irgendetwas passieren? Dass der alte Wert verändert wird, ist ja an sich nicht schlimm, da dieser eh nur temporär existiert...

    void Function(const int& i)
    { 
        const_cast<int&>(i) = 32;
    }
    
    Function(3);
    


  • Die Programmiersprache C++ haelt dich nicht davon ab, dich selbst zu erschiessen. Also was soll die Frage? Beispiel: Ich schreibe eine Methode fuer eine Klasse, die intern eine Art Zaehler veraendert (z.B. find). Diese Methode ist const. Leider kann ich sie nicht als const deklarieren, da sie ja intern am Objekt was veraendert. Nun kann const_cast innerhalb der Methode angewandt auf "this" benutzt werden. (Jaja, es gibt auch mutable aber es ist nur ein Beispiel).

    Ergo kann man sich das ganze const Gedöns sparen.

    Wahrscheinlich hast du const nicht verstanden.



  • Warum geht das:

    void func(const int &x)
    {
        const_cast<int&>(x) = 12;
    }
    

    und das nicht?

    const_cast<int>(i) = 13;
    


  • http://www.cppreference.com/wiki/keywords/const_cast:
    The target data type must be the same as the source type

    Bitte frage jetzt nicht: Warum ist der Himmel blau? Sind wir bald da? ... Google ist dein Freund.


Anmelden zum Antworten