Ausgabe von char *name über cout ?



  • Decimad schrieb:

    std::cout << reinterpret_cast<void*>(name);
    

    Ein static_cast reicht völlig 😉



  • Und ich hab andersherum gedacht: Ein reinterpret_cast reicht völlig!



  • Warum die Brechstange nehmen, wenn der Schraubenzieher reicht?



  • reinterpret_cast behandelt das Objekt sozusagen nur, als wäre es von einem anderen Typ, static_cast enthält auch Konvertierungslogik. Von daher erschließt sich mir der Vergleich mit der Brechstange nicht so ganz.



  • reinterpret_cast kann alles Casten. static_cast nur, wo es Sinn macht.



  • Naja, wir würden da jetzt wohl ewig drüber streiten...



  • Ein reinterpret_cast kann z.B. auch einen int in einen Zeiger casten. Oder zwischen Zeigern casten, die gar nichts miteinander zu tun haben ( double** zu MyClass* ). Das ist in den meisten Fällen ein Fehler (z.B. Schreibfehler) und in noch mehr Fällen schlechter Stil/Designfehler. Mit static_cast hätte es nicht kompiliert. Deshalb sollte man reinterpret_cast nur benutzen, wenn man sich sicher ist, dass man genau den auch braucht. Natürlich ist static_cast nicht langsamer als reinterpret_cast , die Konvertierungslogik wird nur dann angewendet, wenn es Sinn ergibt (z.B. int zu float ), bei Pointern, wo in den meisten Fällen sich das Bitmuster nicht ändert, wird auch nichts gemacht. Übrigens kann auch reinterpret_cast z.B. bei Pointerkonvertierungen Veränderungen vornehmen, also die Bitmuster von Original und Konvertat müssen nicht übereinstimmen (genauer gesagt ist das Verhalten sogar implemention-defined).



  • Decimad schrieb:

    Naja, wir würden da jetzt wohl ewig drüber streiten...

    Ich hoffe mal nicht. Weil das keine Philosophische Sache ist, sondern Grundwissen 😕



  • Ihr legt mir hier alle irgendwie totales Unwissen in den Mund, weil ich der Meinung bin, ein reinterpret_cast um einen char* kurz als void* zu behandeln ist ein legitimes Vorgehen.
    Ich werde dieses Sprachelement einfach nie wieder erwähnen hier! Vielleicht könnt ihr das ja auch verpixeln, damit bloß niemand die Buchstabenkombination lesen kann 😉



  • Decimad schrieb:

    Ihr legt mir hier alle irgendwie totales Unwissen in den Mund, weil ich der Meinung bin, ein reinterpret_cast um einen char* kurz als void* zu behandeln ist ein legitimes Vorgehen.

    Es ist falsch. static_cast ist die korrekte Vorgehensweise. Da gibt es einfach nichts zu diskutieren.

    Du verwendest ja auch keinen reintrepret_cast um von double nach float zu kommen, oder?



  • Nein! Dort will ich ja die mächtigkeit von static_cast auch ausnutzen!



  • Es ist falsch. static_cast ist die korrekte Vorgehensweise. Da gibt es einfach nichts zu diskutieren.



  • Ich sehe halt den Fehler nicht, darum lasse ich es hier auf den Streit jetzt ankommen. 😉 Was ist daran falsch? Dass man auch static_cast hätte hernehmen können macht den Umstand, dass reinterpret_cast verwendet wurde zu einem Fehler? Ist finde ich keine gute Begründung 😉



  • Decimad schrieb:

    Dass man auch static_cast hätte hernehmen können macht den Umstand, dass reinterpret_cast verwendet wurde zu einem Fehler?

    Ja.
    Wenn Du aber sagst, daß es nicht im naturwissenschaftlichen Sinne falsch ist, weil der Compiler es ja frißt, hast Du natürlich recht. Genau genommen ist es nur ein Verbrechen.



  • Dass der Compiler es frisst, muss ja noch lange nicht bedeuten, dass es auch das tut, was ich will, daher werde ich das nicht als Grund anführen! Aber wenn du mir jetzt zeigen kannst, dass es nicht das tut, was will, werde ich eure etwas forschen "Angriffe" so hinnehmen!



  • Es gibt einen ganz klaren objektiven Fakt: der Standard überlässt das Verhalten von reinterpret_cast weitestgehend der Implementierung. D.h., der Cast von char* zu void* könnte bei einer standardkonformen Implementeirung auch z.B. immer 0 liefern. Oder immer 0x123456. Oder das binäre Komplement des Originalzeigers. Die Implementierer sind lediglich angehalten, das Verhalten umzusetzen, das der Nutzer generell erwartet.
    Bei static_cast hingegen ist das Verhalten definiert.

    Darüber hinaus gibt es noch stilbezogene Gründe (reinterpret_cast sollte man wenn immer möglich vermeiden), die will ich jetzt aber nicht groß aufführen. Und im Übrigen kann man die Aussage, dass static_cast "mächtiger" als reinterpret_cast wäre, eigentlich nicht stehen lassen. Beide Cast unterscheiden sich vorwiegend in den erlaubten Konvertierungen und reinterpret_cast übernimmt im Allgemeinen das "Low-Level-Zeug", was man sehr selten wirklich braucht. Außerdem suggeriert die Aussage in dem Fall, dass static_cast langsamer wäre, weil da mehr Logik drin sei. Das stimmt aber nicht.



  • Naja, wie wird denn laut Standard nun ein static_cast von char* auf void* definiert? Kann mir gar nicht vorstellen, dass hier nicht genauso vage auf eine Implementationsabhängigkeit verwiesen wird.

    Mit Mächtigkeit wollte ich zudem nie ausdrücken, dass der cast "langsamer" wäre, das wurde mir in den Mund gelegt.



  • char* auf void* ist so definiert, dass das Zurückcasten des void*-Zeigers in einen (cv) char*-Zeiger wieder den Originalzeiger ergibt. Wie schon erwähnt ist das bei reinterpret_cast nicht der Fall. Da man aber void*-Zeiger generell zur typenlosen Übertragung von Objekten in Schnittstellen nimmt und nicht unbedingt für die Ausgabe des Zeigerwerts, ist das genau die Eigenschaft, die man braucht.



  • Decimad schrieb:

    Naja, wie wird denn laut Standard nun ein static_cast von char* auf void* definiert? Kann mir gar nicht vorstellen, dass hier nicht genauso vage auf eine Implementationsabhängigkeit verwiesen wird.

    Sollte aus irgendeinem Grund ein T* anders als ein U* sein, wäre static_cast korrekt und reinterpret_cast falsch. Denken wir zB an far Pointer oder eeprom Pointer etc. Das sind andere Zeiger als "normale" zB near Pointer oder ram pointer. Hier wäre ein reinterpret_cast falsch und würde zu falschem Code führen während ein static_cast den Fehler Melden würde oder die Konvertierung korrekt machen würde (je nachdem um was für unterschiedliche Zeiger es sich hier handelt).

    Deshalb ist reinterpret_cast hier falsch. Es tut hier zufällig das was du willst, aber du kannst das nicht generalisieren. static_cast ist hier in jeder situation korrekt, reinterpret nur in einigen.

    reinterpret sagt ja: "trust me on this one" - sprich der compiler soll einfach tun und nicht denken. Dh wir deaktivieren hier absichtlich Sicherheitsmechanismen. Und wofür?



  • cout << (void*)name;
    

    spart sogar tipparbeit :p


Anmelden zum Antworten