john 0 erklaert C++ casts
-
@Columbo sagte in Run-Time Check Failure #2:
Hoer auf so einen Schwachsinn zu faseln. Das ist offensichtlich nicht ausreichend.
Der Schwachsinn kommt von dir! Genau aus diesem Grund darf man an dieser Stelle
reinterpret_cast
nicht nutzen, weil es eben fundamentale Fehler überdeckt. Zeiger beliebigen Typs lassen sich mitstatic_cast
konvertieren, wenn das scheitert, dann wird versucht etwas anderes als einen Zeiger zu konvertieren, und dann läuft etwas ganz falsch.
-
Ich benutze C-Style Casts in C++.
Solange man die Casts richtig schreibt erzeugt das weniger Overhead, ist kürzer im Text und macht was verlangt wird.
Es ist keine große Mühe einen Cast richtig zu schreiben und man kann das auch einfach verallgemeinern, dann hat man solche Probleme nicht.
-
@eigenartig sagte in Run-Time Check Failure #2:
Ich benutze C-Style Casts in C++.
C-Casts überdecken etliche Fehler, die man sofort sieht, wenn man C++-Casts verwendet. Wenn man versucht einen vermeintlichen Pointer in einen anderen Pointer mit
static_cast
zu casten, und es funktioniert nicht. Dann versucht man etwas anderes als ein Pointer zu casten, und das schlägt aus gutem Grund fehl. C-Casts funktionieren immer wie ein Dampfhammer, der Cast funktioniert, aber man erzeugt ganz schnell UB.reinterpret_cast
im Kontext von Zeiger braucht man nur dann, wenn man ein Zahl (z.B. konstante Speicheradresse) in einen Zeiger zu konvertieren.
-
@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.
-
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 aufT
in einen Zeiger aufU
zu konvertieren, ist das per Definition dasselbe wie den Zeiger aufT
zuerst mithilfe vonstatic_cast
in einen Zeiger aufvoid
, und das Ergebnis dann mitstatic_cast
in einen Zeiger aufU
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 aufT
in einen Zeiger aufU
zu konvertieren, ist das per Definition dasselbe wie den Zeiger aufT
zuerst mithilfe vonstatic_cast
in einen Zeiger aufvoid
, und das Ergebnis dann mitstatic_cast
in einen Zeiger aufU
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 aufT
in einen Zeiger aufU
zu konvertieren, ist das per Definition dasselbe wie den Zeiger aufT
zuerst mithilfe vonstatic_cast
in einen Zeiger aufvoid
, und das Ergebnis dann mitstatic_cast
in einen Zeiger aufU
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.