john 0 erklaert C++ casts



  • @eigenartig

    Solange man die Casts richtig schreibt erzeugt das weniger Overhead,

    Welchen Overhead?



  • gcc lässt keinen static_cast zwischen beliebigen Zeigertypen zu, und soweit ich weiß auch aus gutem Grund, aber diskutiert hier ruhig weiter. Bin auf das Argument gespannt, warum das eigentlich erlaubt sein sollte.



  • @john-0 sagte in Run-Time Check Failure #2:

    C-Casts funktionieren immer wie ein Dampfhammer, der Cast funktioniert, aber man erzeugt ganz schnell UB.

    Sollen sie auch. Ich finde es fragwürdig einen Cast falsch zu schreiben.

    @manni66 sagte in Run-Time Check Failure #2:

    Welchen Overhead?

    Außer bei dynamic_cast<> wohl keinen.


  • Mod

    Wurde mir zu bloed, diesen Unsinn im OT zu ertragen. Uns kann @john-0 hier gerne erklaeren, ob

    struct T {}; 
    char* p;
    static_cast<T*>(p); 
    

    wohlgeformt ist, nachdem er es fuer notwendig befand, in fettgedrucktem Text zu widersprechen (spoiler: nicht einmal VC++ ist so bescheuert, das zu uebersetzen).

    Strapaziere nicht den Geduldsfaden.



  • @Columbo sagte in john 0 erklaert C++ casts:

    Wurde mir zu bloed, diesen Unsinn im OT zu ertragen.

    Du missbrauchst deine Rolle als Mod massiv. Namen von Nutzern als Threadtitel zu wählen ist niveaulos, und dazu schreibst du zu den technischen Belangen gröbsten Unfug (siehe ursprünglicher Thread was mit reinterpret_cast alles falsch gehen kann).

    Uns kann @john-0 hier gerne erklaeren, ob

    struct T {}; 
    char* p;
    static_cast<T*>(p); 
    

    Das geht problemlos via

    struct T{};
    
    char*p;
    void* pv = static_cast<void*>(p);
    T* pT = static_cast<T*>(pv);
    

    Ok, ich habe den zweiten Casts vergessen, aber es ist kein fundamental Fehler.



  • void* ist also sicherer als reinterpret_cast - ja dann ...



  • Wenn reinterpret_cast benutzt wird, um einen Zeiger auf T in einen Zeiger auf U zu konvertieren, ist das per Definition dasselbe wie den Zeiger auf T zuerst mithilfe von static_cast in einen Zeiger auf void, und das Ergebnis dann mit static_cast in einen Zeiger auf U zu konvertieren.

    Bin aber immer noch gespannt, wer hier jetzt genau Schwachsinn erzählt hat 🙂



  • @Bashar sagte in john 0 erklaert C++ casts:

    Wenn reinterpret_cast benutzt wird, um einen Zeiger auf T in einen Zeiger auf U zu konvertieren, ist das per Definition dasselbe wie den Zeiger auf T zuerst mithilfe von static_cast in einen Zeiger auf void, und das Ergebnis dann mit static_cast in einen Zeiger auf U zu konvertieren.

    Das Problem bei reinterpret_cast ist, dass man da mit nicht nur die Zeiger konvertieren kann, sondern

    #include <cstdlib>
    
    struct Foo{};
    
    int main () {
        size_t s = 1;
        Foo* pF = reinterpret_cast<Foo*>(s);  // 1
        Foo* p  = reinterpret_cast<Foo*>(&s); // 2
    }
    

    auch das hier. Wenn Du den Unterschied zwischen Zeile 1 und 2 verstanden hast, dann können wir weiter diskutieren.



  • @john-0 sagte in john 0 erklaert C++ casts:

    @Bashar sagte in john 0 erklaert C++ casts:

    Wenn reinterpret_cast benutzt wird, um einen Zeiger auf T in einen Zeiger auf U zu konvertieren, ist das per Definition dasselbe wie den Zeiger auf T zuerst mithilfe von static_cast in einen Zeiger auf void, und das Ergebnis dann mit static_cast in einen Zeiger auf U zu konvertieren.

    Das Problem bei reinterpret_cast ist, dass man da mit nicht nur die Zeiger konvertieren kann, sondern

    #include <cstdlib>
    
    struct Foo{};
    
    int main () {
        size_t s = 1;
        Foo* pF = reinterpret_cast<Foo*>(s);  // 1
        Foo* p  = reinterpret_cast<Foo*>(&s); // 2
    }
    

    auch das hier. Wenn Du den Unterschied zwischen Zeile 1 und 2 verstanden hast, dann können wir weiter diskutieren.

    das geht aber doch mit dem C-Style-Cast genauso ( Zeile 1 ist gemeint ) ....



  • @It0101 sagte in john 0 erklaert C++ casts:

    das geht aber doch mit dem C-Style-Cast genauso ( Zeile 1 ist gemeint ) ....

    Ja, und deshalb sollte man weder C-Style-Casts noch reinterpret_cats verwenden, wenn dies nicht unbedingt notwendig ist. Du musst nur ein "&" oder "*" vergessen und schon hast Du UB ins Programm eingebaut und der Compiler wirft keinerlei Warnung aus.



  • @john-0 sagte in john 0 erklaert C++ casts:

    Das geht problemlos via

    struct T{};
    
    char*p;
    void* pv = static_cast<void*>(p);
    T* pT = static_cast<T*>(pv);
    

    Das kompiliert zwar, aber es ist trotzdem fürchterlich.



  • @john-0 sagte in john 0 erklaert C++ casts:

    @It0101 sagte in john 0 erklaert C++ casts:

    das geht aber doch mit dem C-Style-Cast genauso ( Zeile 1 ist gemeint ) ....

    Ja, und deshalb sollte man weder C-Style-Casts noch reinterpret_cats verwenden, wenn dies nicht unbedingt notwendig ist. Du musst nur ein "&" oder "*" vergessen und schon hast Du UB ins Programm eingebaut und der Compiler wirft keinerlei Warnung aus.

    Da stimme ich dir zu. C-Style-Casts und auch reinterpret sollten absolute Ausnahmen sein. Ich brauche die Schlampen-Casts ( so fasse ich die zusammen ) eigentlich fast nie. Eigentlich caste ich überhaupt relativ selten. Ist auch heutzutage selten notwendig, wenn man sauber mit Templates und Vererbung arbeitet.

    Ich benutze diese Casts eigentlich nur hardware-nah bei der Speicherbesorgung und eben bei Puffern, wenn man z.B. den Typ kennt, der als nächstes im Puffer folgt, dann caste ich auch mal von char* nach T*.



  • @It0101 sagte in john 0 erklaert C++ casts:

    Das kompiliert zwar, aber es ist trotzdem fürchterlich.

    Es ist eine Folge des gewählten Designs.



  • Ich habe eigentlich nicht verstanden warum ihr euch hier so in die Haare bekommt.
    Dass C-Style und reinterpret_cast zu vermeiden sind, ist doch eigentlich Konsens.



  • C-Style Casts sind viel übersichtlicher und nicht in langnamigen Funktionen versteckt. Ausnahmen für mich sind hier std::move() weil der Name vergleichsweise besser aussieht.

    So schlimm kann das schon nicht sein das richtig zu machen.



  • @eigenartig sagte in john 0 erklaert C++ casts:

    C-Style Casts sind viel übersichtlicher und nicht in langnamigen Funktionen versteckt

    Hast du kein Intellisense / Autovervollständigen?
    Für die meisten Befehle muss ich gerade mal vier Buchstaben eingeben.

    Also das schlampige Arbeiten mit "ich will nicht soviel tippen" zu begründen, ist in der heutigen Zeit schon bedenklich 😉 Nichts für ungut.



  • @It0101 sagte in john 0 erklaert C++ casts:

    Also das schlampige Arbeiten mit "ich will nicht soviel tippen" zu begründen, ist in der heutigen Zeit schon bedenklich Nichts für ungut.

    Das stimmt doch gar nicht. Es ist einfach viel hübscher nur (T) zu verwenden.



  • @It0101 sagte in john 0 erklaert C++ casts:

    Ich habe eigentlich nicht verstanden warum ihr euch hier so in die Haare bekommt.

    Der Herr reagiert sehr dünnhäutig darauf, wenn man seinen Stil zu programmieren kritisiert. Einige hier im Forum hängen einer Ideologie an, dass man keinerlei manuelle Speicherverwaltung machen dürfe. Das führt dann in diesem konkreten Beispiel zu einem zweifelhaften Design. Wann wenn nicht in einem Container sollte man manuelle Speicherverwaltung machen?

    P.S. Wie man es ohne cast hinbekommt, habe ich im original Thread mittlerweile gepostet. Das ist die Minimallösung. Die saubere Lösung wäre die Containerklasse komplett mit eigener Speicherverwaltung zu schreiben, und dann wird auch schnell ersichtlich, weshalb propagate_on_container_swap, propagate_on_container_copy_assigment, propagate_on_container_move_assigment alles andere als Trivialitäten sind.



  • @eigenartig sagte in john 0 erklaert C++ casts:

    C-Style Casts sind viel übersichtlicher

    Sie verdecken Fehler, und das ist ein Problem. Dazu kann man dynamic_cast nicht durch einen C-Cast ersetzen.



  • @john-0 sagte in john 0 erklaert C++ casts:

    Sie verdecken Fehler, und das ist ein Problem.

    C++-Style Casts können auch falsch benutzt werden. Darüber streitet ihr euch doch.

    @john-0 sagte in john 0 erklaert C++ casts:

    Dazu kann man dynamic_cast nicht durch einen C-Cast ersetzen.

    Eine Klasse mittels dynamic_cast<> herauszufinden ist sowieso fragwürdiges Design.


Anmelden zum Antworten