casten



  • Au,.. so viele schöne kontras 🙂

    Nexus schrieb:

    Und was der Assemblercode an dieser Stelle soll, erschliesst sich mir nicht.
    Aber wie schon im anderen Thread ist er ein schlechtes Argument.

    ..um präzise zu sein, ist das kein Argument sondern ein Beweissmitteln zur untermauerung meiner Argumentation...

    Nexus schrieb:

    Und wie du auf Konvertierungsoperatoren (das sind die Memberfunktionen) kommst, weiss ich auch nicht.

    Ok, mal gucken ob ich Dir es so näher bringen kann... (Schau es Dir aber auch an)

    Um die mechanismen zu verstehen, die man benutzt, muss man sich auch anschauen
    wie diese umgesetzt werden. Das mache ich jetzt (nochmal... ich weiß jaja 🙂 )

    Als C -Style Cast bezeichne ich:

    Object_A objA;
    Object_B B = (Object_B) objA;
    

    Im konkreten Fall bei einem Casting eines Objectes zu einem Basistypen:

    Test a;
    012A7B7B  lea         ecx,[a] 
    012A7B81  call        Test::Test (12A86F0h) 
    
    double d=(double)a;
    012A7B86  lea         ecx,[a] 
    012A7B8C  call        Test::operator double (12A8710h) 
    012A7B91  fstp        qword ptr [d] 
    
    double*e=(double*)a;
    012A7B97  lea         ecx,[a] 
    012A7B9D  call        Test::operator double * (12A8730h) 
    012A7BA2  mov         dword ptr [e],eax
    

    Für das Object:

    class Test
    {
    private:
    	double d;
    public:
    	Test(){};
    	operator double() { return this->d;};
      	operator double*() { return &this->d;};
    };
    

    Wie man in der assembly sehen kann, wird der C_Cast auf die spezifischen
    casting operator umgeleitet.

    Das Argument bezog sich darauf, das ein C_Cast in der übersetzung keine
    "Umbiegung" ist, sondern explicit nach einer definierten Konvertierung gesucht und ersetzt wird.
    Das ist bei der deklaration von dem Casting operator "operator double()" der
    Fall". Das gleiche gilt für einen RVALUE type void*, sofern dieser implementiert ist.

    Die Folgerung dieses Beispiels ist:
    Wenn man ein Object casten will, kann man das laufzeitkonvertierungsmechanismen
    überlassen, die auch auf korrektheit des typs prüfen können. Und das mit
    C Style Casts, die ja wie oben gezeigt, wenn implementiert, in Casting Methoden
    umegeleitet werden.

    Frage: Ist diese Folgerung falsch?

    Nexus schrieb:

    Nur schade, dass hier nirgends ein C-Cast im Spiel ist...

    Bezog sich eher auf die (nicht) notwendigkeit von const_cast,....
    das kam vlt. nicht so rüber...

    Shade Of Mine schrieb:

    class A {
    private:
       int i;
    
    public:
    	A() { i=0;};
    	A(const A& a) { this->i=a.getI(); };
       int getI() const { return const_cast<A*>(this)->getI(); }
       int& getI() { return i; }
    };
    

    Ein schönes Beispiel.
    Da aber getI() nicht komplex ist reicht auch:

    int &getI() { return i;}
    int const &getI() const { return i;}
    

    Hast Du vlt. noch ein anders Beispiel?

    DocShoe schrieb:

    und indem du eine Funktion mit einem void Pointer hast, bei der der Pointer auf
    eine Klasse zeigt ist der Ansatz doch schon völlig falsch. Entweder benutzt
    man statischen Polymorphismus durch templates oder Laufzeitpolymorphismus durch Vererbung.

    Ja, da hast du recht.
    Dabei bezog ich mich aber auf Beispiele für den Verwendungszweck, welche in
    referenzen von reinterpret_cast vorliegen:
    http://msdn.microsoft.com/en-us/library/e0w9f63b(VS.80).aspx
    Das reicht aber um den worst case des Anwendungsfalls zu verdeutlichen.

    hustbear schrieb:

    Aber bewirb es bloss nicht hier, oder behaupte dass C++ Style Casts deswegen
    unnötig wären, weil du nicht verstanden hast wozu sie gut sind (oder sie
    einfach trotzdem nicht verwenden willst).

    Mensch hustbear, ich habe doch schon in einem vorherigen Post geschrieben was
    meine intension ist. Aber Dir zu liebe nochmal:

    ich schrieb:

    Das Ziel meiner Argumentation ist, die Aussage verständlich zu machen:
    "Es reicht C_Cast zu benützen!"
    (Ich habe nicht gesagt: macht das alle so, sonst gibt auf die nuss 😉 )
    ...
    P.S.: Ziel der diskussion ist die Casting methoden auseinander zu nehmen und zu
    Erörtern... Nicht Euch meine meinung aufzustempeln! ⚠

    Ich habe nicht gesagt das ein C_Cast kein reinterpret_cast, kein static_cast, kein const_cast und auch kein dynamic_cast macht.

    Das was ich sage ist: Wenn man weiß, und testet, wie der (oder ein) C_Cast
    sich auf das datensegment von einem Basistyp oder anderes Object (oder ptr) auswirkt,
    sowie methoden und/oder funktionen implementiert die eine richtige Behandlung und Prüfung zur Kompilierzeit und zur Laufzeit sicherstellen, dann sind
    (oder sollten) alle relevanten qualitätsmerkmale (á la SQuaRE) erfüllt sein.

    Es ist natürlich richtig das jede meldung im Compiler das Leben des Programmierers vereinfacht und gerade unter Termindruck flüchtigkeitsfehler
    ausschließen will.

    Wenn ich vergessen habe auf irgendein statement von euch genauer einzugehen, sagt nochmal bÖscheid.

    grüüßli 😃



  • Machen denn hier der C-Style cast und der static_cast auch das gleiche?

    class A;
    class B;
    
    B& toB1( A& aA )
    {
            return (B&)aA;
    }
    
    B& toB2( A& aA )
    {
            return static_cast<B&>(aA);
    }
    


  • zeusosc schrieb:

    Ok, mal gucken ob ich Dir es so näher bringen kann... (Schau es Dir aber auch an)

    Du solltest bedenken dass Nexus von C++ ein paar Ecken mehr versteht als du bevor du solche Formulierungen verwendest...

    Wenn man ein Object casten will, kann man das laufzeitkonvertierungsmechanismen
    überlassen, die auch auf korrektheit des typs prüfen können. Und das mit
    C Style Casts, die ja wie oben gezeigt, wenn implementiert, in Casting Methoden
    umegeleitet werden.

    Frage: Ist diese Folgerung falsch?

    Ja. Sie ist komplett falsch.
    Natürlich findest du Situationen wo C Casts genau das richtige tun. Es ist ja nicht so als wären sie kaputt und würden nicht funktionieren. Aber das geht eben komplett am Thema vorbei. Schau dir mein Codebeispiel mal an (und vergiss den Assembler Code der sagt nichts aus):

    class A {}; 
    class B {}; 
    
    void f(B const& b) {} 
    
    int main() { 
       A a; 
       f((B const&)a);  //geht 
       //f(static_cast<B const&>(a)); //geht nicht 
    }
    

    Ein simpler, einfacher Gegenbeweis.
    C Casts machen böse Sachen. Die Konvertierung von a nach B ist illegal. C Casts machen sie dennoch. Das ist Gefährlich. Deshalb: c++ casts verwenden.

    Bezog sich eher auf die (nicht) notwendigkeit von const_cast,....

    Du kannst nicht mit einem Beispiel wo X nicht notwendig ist Beweisen, dass X nie notwendig ist. So funktioniert das nicht.

    Ein schönes Beispiel.
    Da aber getI() nicht komplex ist reicht auch:

    int &getI() { return i;}
    int const &getI() const { return i;}
    

    Stell dir einfach vor getI sei komplex. Man kann immer etwas drum herum bauen - klar. Aber das hier ist ein Fall wo man idR mit const_cast am besten fährt.

    Hast Du vlt. noch ein anders Beispiel?

    Klar. Wenn man eine API verwenden muss die nicht const-correct ist.

    Das Ziel meiner Argumentation ist, die Aussage verständlich zu machen:
    "Es reicht C_Cast zu benützen!"

    Wie schon gesagt: nur weil man etwas machen kann, ist es noch lange keine gute Idee. C Casts sind eine furchtbar dumm Idee. Aber klar, ich kann auch freihändig mit dem Auto auf der Autobahn fahren. Klar geht das. Aber eine gute Idee ist etwas anderes.

    Das was ich sage ist: Wenn man weiß, und testet, wie der (oder ein) C_Cast
    sich auf das datensegment von einem Basistyp oder anderes Object (oder ptr) auswirkt,
    sowie methoden und/oder funktionen implementiert die eine richtige Behandlung und Prüfung zur Kompilierzeit und zur Laufzeit sicherstellen, dann sind
    (oder sollten) alle relevanten qualitätsmerkmale (á la SQuaRE) erfüllt sein.

    Du erreichst mit enromen mehr Aufwand ein fast so gutes Ergebnis wie mit C++ Casts. Ja.


  • Mod

    zeusosc schrieb:

    ...

    Wie man in der assembly sehen kann, wird der C_Cast auf die spezifischen
    casting operator umgeleitet.

    Das Argument bezog sich darauf, das ein C_Cast in der übersetzung keine
    "Umbiegung" ist, sondern explicit nach einer definierten Konvertierung gesucht und ersetzt wird.

    Worauf willst du eigentlich hinaus? Es ist schon klar, dass genau definiert ist, was der C-Cast macht. Es geht darum, dass man es ihm nicht unbedingt ansieht, weil er alles machen könnte. Einmal nicht aufgepasst (egal ob an Stelle des Casts oder irgendwo weit vorher) -> kein Compilerfehler, aber dafür semantischer Fehler im Programm. Sehr schwer zu finden. Besonders da man die C-Casts noch nicht einmal gut suchen kann.

    Bezog sich eher auf die (nicht) notwendigkeit von const_cast,....
    das kam vlt. nicht so rüber...

    Schön. const_cast ist auch nicht nötig und wenn man es doch braucht, dann ist das ein Warnsignal, dass etwas falsch ist. Wieso wolltest du nochmal einen Cast benutzen, der const_cast mit beinhaltet und bei dem man nicht einmal merkt, dass man ihn benutzt?

    Ja, da hast du recht.
    Dabei bezog ich mich aber auf Beispiele für den Verwendungszweck, welche in
    referenzen von reinterpret_cast vorliegen:
    http://msdn.microsoft.com/en-us/library/e0w9f63b(VS.80).aspx
    Das reicht aber um den worst case des Anwendungsfalls zu verdeutlichen.

    Schön. reinterpret_cast ist auch nicht nötig und wenn man es doch braucht, dann ist das ein Warnsignal, dass etwas falsch ist. Wieso wolltest du nochmal einen Cast benutzen, der reinterpret_cast mit beinhaltet und bei dem man nicht einmal merkt, dass man ihn benutzt?

    "Es reicht C_Cast zu benützen!"

    Es gibt viele Sachen die ausreichend sind, aber deshalb ist es noch lange nicht gut, so zu handeln.

    Das was ich sage ist: Wenn man weiß, und testet, wie der (oder ein) C_Cast
    sich auf das datensegment von einem Basistyp oder anderes Object (oder ptr) auswirkt,
    sowie methoden und/oder funktionen implementiert die eine richtige Behandlung und Prüfung zur Kompilierzeit und zur Laufzeit sicherstellen, dann sind
    (oder sollten) alle relevanten qualitätsmerkmale (á la SQuaRE) erfüllt sein.

    Schön. Also anstatt eine semantische Prüfung durch den Compiler automatisiert vorzunehmen, soll ich jetzt umfangreiche Tests machen. Da habe ich ja echt viel gewonnen 🙄 .

    Es ist natürlich richtig das jede meldung im Compiler das Leben des Programmierers vereinfacht und gerade unter Termindruck flüchtigkeitsfehler
    ausschließen will.

    Warum willst du sie dann umgehen?



  • zeusosc schrieb:

    hustbear schrieb:

    Aber bewirb es bloss nicht hier, oder behaupte dass C++ Style Casts deswegen
    unnötig wären, weil du nicht verstanden hast wozu sie gut sind (oder sie
    einfach trotzdem nicht verwenden willst).

    Mensch hustbear, ich habe doch schon in einem vorherigen Post geschrieben was
    meine intension ist. Aber Dir zu liebe nochmal:

    ich schrieb:

    Das Ziel meiner Argumentation ist, die Aussage verständlich zu machen:
    "Es reicht C_Cast zu benützen!"
    (Ich habe nicht gesagt: macht das alle so, sonst gibt auf die nuss 😉 )
    ...
    P.S.: Ziel der diskussion ist die Casting methoden auseinander zu nehmen und zu
    Erörtern... Nicht Euch meine meinung aufzustempeln! ⚠

    Ich habe nicht gesagt das ein C_Cast kein reinterpret_cast, kein static_cast, kein const_cast und auch kein dynamic_cast macht.

    Das was ich sage ist: Wenn man weiß, und testet, wie der (oder ein) C_Cast
    sich auf das datensegment von einem Basistyp oder anderes Object (oder ptr) auswirkt,
    (...)

    Mal abgesehen davon dass du eine sehr eigenwillige (und IMO total falsche) Interpretation von "Datensegment" hast...

    Ja, wenn man weiss was man tut kann man auf C++ Style Casts verzichten, solange man keinen dynamic_cast braucht.
    Nur wieso sollte man das wollen?
    Wenn man weiss was man tut kann man wie gesagt auf viel verzichten. Man kann überall das const weglassen und statt T const& überall T& rumreichen. Führt zu toll unwartbarem Code.
    Genauso führt IMO die Verwendung von C-Style Casts zu toll unwartbarem Code.

    Dass es geht wurde jetzt glaube ich schon oft genug festgestellt. Also worum geht es dir jetzt noch, abgesehen von dieser (IMO ziemlich wertlosen) Feststellung?



  • @Shade:

    Ich wollte niemanden ans Bein pinkeln. Sollte es so rübergekommen sein, dann
    entschuldige ich mich gerne. Ich hatte bei der Aussage zu Nexus nur den eindruck
    er hätte mein Post zu rasch überflogen... Daher entschuldige Nexus...

    @Shade + SeppJ:
    Eure beiden aussagen (mal zusammengefasst)
    "Mit mehr aufwand für ein ordentliches C_Cast erreicht man das gleiche wie
    es die C++ Style Casts schon (viel einfacher) machen!" finde ich gut und bringt
    die sache glaube ich auch auf exakt den Punkt. 🕶

    Blöd ist: ich habe jetzt summa sumarum keine Gegenargumente mehr ...

    Daher thx at all 👍
    ---------------------------------------
    Edit:

    hustbear schrieb:

    Dass es geht wurde jetzt glaube ich schon oft genug festgestellt. Also worum geht es dir jetzt noch, abgesehen von dieser (IMO ziemlich wertlosen) Feststellung?

    Das wars eigentlich schon,.. trozdem danke 🙂



  • Siiiiieg 😉


Anmelden zum Antworten