casten
-
Shade Of Mine schrieb:
zeusosc schrieb:
Das Ziel meiner Argumentation ist, die Aussage verständlich zu machen:
"Es reicht C_Cast zu benützen!"Es reicht Assembler zu benützen.
haha,.. ja

Shade Of Mine schrieb:
PS:
Bei einem C_Style Cast oder einer direkten zuweisung mit implizitem casting,
wird gecheckt ob ein passender konvertierungsmechanismus vorhanden ist.Nein. Ein C Cast nimmt den Wert und steckt ihn in den Typen rein. Egal was.
Egal wer. Egal wo. Du willst aus einem Vogel ein Auto machen? -> C Cast kann das.Nö,.. das ist schlichtweg falsch. Ein C_Cast unter einem C++ Compiler prüft ob
dementsprechende operanden (Konvertierungsmechanismen) vorhanden sind
und ersetzt diese dann:Test a; 00297B7B lea ecx,[a] 00297B81 call Test::Test (2986F0h) Test b(a); 00297B86 lea eax,[a] 00297B8C push eax 00297B8D lea ecx,[b] 00297B93 call Test::Test (298710h) double d=(double)b; 00297B98 lea ecx,[b] 00297B9E call Test::operator double (298760h) 00297BA3 fstp qword ptr [d]Shade Of Mine schrieb:
Ein reintrepret_cast ist fast wie ein C cast, mit dem unterschied dass er auf
const correctness achtet. dh wenn ich einen reintrepret_cast sehe, dann weiss
ich sofort: Achtung, da wird an den typen rumgemurkst - aber wenigstens kann
ich mich auf const correctness verlassen.int *k=0; const int j=5; k=reinterpret_cast<int*>(&j); // ERROR: C2440 cannot convert from 'const int *' to 'int *' //1> Conversion loses qualifiers *k=3;Richtig.. kann man,...
Braucht man es wenn die schnittstelle definiert das es ein const sein muss?Shade Of Mine schrieb:
Und const_cast ist super um zu sagen: hier tue ich nur das const wegnehmen. Das ist sofort eine rote Flagge: Warum will ich das? Aber ich weiss sofort was hier passiert.
A) Wenn ich nicht erkenne, wo das explicite typensystem unterlaufen wird, ist:
I) Der Source schlecht dokumentiert
II) Der Source unübersichtlich gestaltet
III) Die Schnittstelle nicht ausreichend definiertÄh, schonmal mit großen Projekten gearbeitet? Das mag in der Theorie ja gut
klingen, dass du durch guten Code und gute Doku immer auch einen C Casts auf
genau einen Verwendungszweck reduzieren kannst - in der Praxis ist das aber
nicht möglich.Und ob das möglich ist,... nehmen wir ein beispiel:
class Test { private: bool a; public: bool Methode_a(void) { return this->a; } Test & operator=(const Test &b) { if(this==&b) return *this; this->a=b.Methode_a(); //error C2662: 'Test::Methode_a' : cannot convert 'this' pointer from 'const Test' to 'Test &' 1> Conversion loses qualifiers return *this; };Füge ich hingegen eine
const-Qualifizierte überladung durch:bool Methode_a(void) const { return this->a; }Wird ohne Murksen kompiliert. Und das auch mit grund.
Setzt man das in verbindung mit den casting operatoren,
schon hat man einconst safe type (C Style) casting
,....Nehmen wir noch ein anderes Beispiel:
Test& Eine_Beispiel_Function( const void * foo) { Test * a = ( const Test*) foo; // error: cannot convert from 'const Test *' to 'Test *' a=(Test*)foo; //kein error <- einzige variante die einen fehler verursachen könnte, wenn man in der behandlung nicht aufpasst a=reinterpret_cast<const Test*>(foo); // error: cannot convert from 'const Test *' to 'Test *' a=reinterpret_cast<Test*>(foo); //error: cannot convert from 'const void *' to 'Test *' const Test *b=(Test*) foo; //kein error, und auch nicht falsch b= reinterpret_cast<Test*>(foo); //error: cannot convert from 'const void *' to 'Test *' b=(const Test*)foo;//kein error, und auch nicht falsch b=reinterpret_cast<const Test*>(foo);//kein error und auch net falsch return *a; };D.h. ist eine
constEigenschaft für das element über die deklaration
gegeben, so muss ich die natürlich für den gecasteten typen übernehmen..const Test * b= (Test*) foo;ist für die behandlung mehr als ausreichend, wenn ein cast
auf ein element dasconst-attribut erforderlich ist.Ich kenne (also) kein Beispiel das mir die Erforderniss von
const_castundreinterpret_castklar macht (unter berücksichtigung benannter typenbehandlung)!Shade Of Mine schrieb:
Bedenke, dass ein c casts all das macht, was du in C++ bei den casts für
unnötig befindest. Wenn du zB sagst const und reintrepret sind unnötig: dann
bedenke dass ein C cast genau das aber macht. Ein C casts ist eine const-static-
reintrepret Mischung die ALLES erlaubt.Unter einem C++ Kompiler macht ein C_Cast das eben nicht.
Dieser wird wie ein konvertierungs-operator behandelt (siehe gaaanz oben in diesem Post)
welche ausreichend deklariert und definiert werden müssen.
Verzichtet man hingegen darauf, ist es klar das die typenbehandlung ausgelagert werden muss.
Grüüüüüüße
-
@zeusosc:
C++ Style Casts sind genau so nützlich oder unnütz wieconst, dass Integers nicht automatisch zu Enum Typen konvertiert werden dürfen, dass void-Pointer nicht automatisch in typisierte Zeiger konvertiert werden dürfen und 100 andere Sachen in C++, die nur dazu da sind Fehler zu vermeiden.Wenn du lieber etwas schreibst wo der Compiler viel weniger Chancen hat von dir unbeabsichtigte Fehler zu finden: fein. Mach es so. 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).
Unter einem C++ Kompiler macht ein C_Cast das eben nicht.
Dieser wird wie ein konvertierungs-operator behandelt (siehe gaaanz oben in diesem Post)
welche ausreichend deklariert und definiert werden müssen.Ein C Style Cast macht unter C++ so ziemlich alles, inklusive const_ und reinterpret_cast. Steht auch so im Standard.
-
Gerade dein Beispiel "Eine_Beispiel_Function widerlegt" doch das, was du uns nahebringen willst: Die Kernaussage ist "be precise", 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.
Deine Funktion erlaubt es, Birnenbäume zu übergeben und erwartet Fensterhandles, robuste Programmierung ist etwas anderes.
Casts werden dazu benutzt, um Brücken zu schlagen, wobei dir bei den C++ casts der Compiler klar sagt, welche Brücken erlaubt sind und welche nicht, d.h. er erkennt bereits zur Compile time mögliche Fehler und garantiert Typsicherheit. Bei C casts ist das eben nicht so, das ist wie Hochseilakrobatik ohne Netz. Geht meistens gut, muss aber nicht, und wenn nicht, dann fatal. Allein diese Tatsache macht diese Diskussion hinfällig, wenn jemand so programmieren möchte kann er das gerne tun, aber die Behauptung, das sei besserer Stil und schneller lässt mich aus der Diskussion aussteigen. Über Nonsens diskutiert man nicht, Punkt.
-
zeusosc schrieb:
Nö,.. das ist schlichtweg falsch. Ein C_Cast unter einem C++ Compiler prüft ob
dementsprechende operanden (Konvertierungsmechanismen) vorhanden sind
und ersetzt diese dann: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 }Der Rest deines Posts ist etwa genauso wahr wie diese Aussage.
Deshalb beende ich es für mich.Nur weil du ein Beispiel bringst wo const cast nicht notwendig ist, heisst es nicht dass const cast NIE notwendig ist. btw c casts sind immer auch const casts...
Ich kenne (also) kein Beispiel das mir die Erforderniss von
const_cast und reinterpret_cast klar macht (unter berücksichtigung benannter typenbehandlung)!const cast Beispiel:
class A { private: int i; public: int getI() const { return const_cast<A*>(this)->getI(); } int& getI() { return i; } };Stell dir vor getI sei komplex.
Beispiel für reintrepret_cast:
int buffer; char* bytes; bytes = reinterpret_cast<char*>(&buffer);Du willst zB ein Sammlung von ints als einzelne Bytes behandeln bzw. einen Bytestrom als eine Ansammlung von ints.
Es gibt millionen Fälle wo dieser oder jener Cast praktisch ist. Bedenke bitte: der C Cast macht immer reintrepret+const Cast.
-
zeusosc schrieb:
Nö,.. das ist schlichtweg falsch. Ein C_Cast unter einem C++ Compiler prüft ob
dementsprechende operanden (Konvertierungsmechanismen) vorhanden sind
und ersetzt diese dannEin C-Cast versucht die Typen irgendwie umzubiegen. Sofern das geht, wird es getan. Darunter fallen viele unerwünschte Fälle.
Und was der Assemblercode an dieser Stelle soll, erschliesst sich mir nicht. Aber wie schon im anderen Thread ist er ein schlechtes Argument.
zeusosc schrieb:
Und ob das möglich ist,... nehmen wir ein beispiel:
bool Methode_a(void) { return this->a; } Test & operator=(const Test &b) { if(this==&b) return *this; this->a=b.Methode_a(); //error C2662: 'Test::Methode_a' : cannot convert 'this' pointer from 'const Test' to 'Test &' 1> Conversion loses qualifiers return *this; };Nur schade, dass hier nirgends ein C-Cast im Spiel ist...
zeusosc schrieb:
Unter einem C++ Kompiler macht ein C_Cast das eben nicht.
Natürlich ist ein C-Cast die Kombination von
static_cast,reinterpret_castundconst_castund je nachdem wird auch mehreres auf einmal angewandt. Und wie du auf Konvertierungsoperatoren (das sind die Memberfunktionen) kommst, weiss ich auch nicht.
-
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],eaxFü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 vonreinterpret_castvorliegen:
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.
-
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 vonreinterpret_castvorliegen:
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_castbraucht.
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 stattT const&überallT&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
