Statt static_cast, das die Cast-Operation zur Übersetzungszeit prüft,
2
könnten Entwickler dynamic_cast verwenden: Es kontrolliert die
3
Vererbungshierarchie zur Laufzeit und verweigert fehlerhafte Downcasts.
4
Die Prüfung ist jedoch zeitaufwendig, weshalb zum Beispiel Mozilla
5
dynamic_cast in Firefox-Code verbietet.
6
7
...
8
9
Ein mit CaVer übersetzter Chrome-Browser läuft nach Angaben der
10
Wissenschaftler rund 7 Prozent langsamer, Firefox über 64 Prozent langsamer.
11
In Googles Browser prüfte es dabei rund 150.000 Cast-Operationen, bei
12
Firefox waren es über 1 Million.
Bei sovielen casts ist es kein wunder, wenn da mal was schief geht.
Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache
sicherer macht, verboten wird.
Kaj G. schrieb:> Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache> sicherer macht, verboten wird.
Das wiederum ist durchaus verständlich.
Sobald irgendwo im Code ein "dynamic_cast" verwendet wird, muss quer
durch alles mit RTTI kompiliert werden. d.H. ein einziger Cast in nur
einem Source-File, auch wenn er nie ausgeführt wird, macht potentiell
alles andere langsamer, verschwendet Speicher usw.
RTTI ist beim GCC z.B. jetzt recht gut implementiert, mit minimalem
Overhead. Das muss aber nicht bei allen Compilern so sein.
Kaj G. schrieb:> Bei sovielen casts ist es kein wunder, wenn da mal was schief geht.> Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache> sicherer macht, verboten wird.
Die Verwendung von `dynamic_cast` ist häufig ein Hinweis auf ein
kaputtes design. Nicht jeder dynamic_cast kann durch einen static_cast
ersetzt werden.
Wenn er ersetzt werden kann, dann macht er bei fehlerfreier Software
funktional auch keinen Unterschied, er benötigt aber mehr Ressourcen.
Wenn er Software-Fehler finden soll, dann würde man ihn ggf. wie ein
assert einsetzen:
Kaj G. schrieb:> Bei sovielen casts ist es kein wunder, wenn da mal was schief geht.> Schlimmer finde ich allerdings, das ein Sprachmittel, was die Sprache> sicherer macht, verboten wird.
?
Falscher Ansatz.
Wenn in einem Programm exzessiv gecastet werden muss, dann ist am Design
was faul!
In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts
vor.
Karl H. schrieb:> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts> vor.
Wobei ich mir grad bei einem Browser und den durch DOM vorgegebenen
Strukturen vorstellen kann, dass upcasts öfter mal nötig sind.
Aber: die DOM-Elemente enhalten sowieso Infos über Ihre "Class" in einem
Member, führen also ihr eigenes "RTTI-Light" mit.
Dann sind alle Stellen, bei denen ein dynamic_cast ein anderes Ergebis
als ein static_cast bringt, Hinweise auf einen handfesten Fehler.
==> Die "assert"-Lösung von Thorsten hift.
Planlos schrieb:> Karl H. schrieb:>> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts>> vor.>> Wobei ich mir grad bei einem Browser und den durch DOM vorgegebenen> Strukturen vorstellen kann, dass upcasts öfter mal nötig sind.
Öfter mal, ok.
Aber nicht 1 Million
Karl H. schrieb:> Öfter mal, ok.> Aber nicht 1 Million
Naja, wer weis, wie die gezählt haben. Vielleicht ist da ein cast in
einem häufig verwendeten Macro.
https://labs.mwrinfosecurity.com/blog/2013/04/19/mwr-labs-pwn2own-2013-write-up---webkit-exploit/
Sag ich doch: Designfehler.
Entweder in einem SVG Document ist alles ein SVGElement oder ich kann
das so nicht Casten. Wenn aber alles ein SVGElement ist, dann brauch ich
den Cast in erster Linie gar nicht, weil von getElementById gar nichts
anderes als ein SVGElement oder eien davon abgeleitete Klasse zurück
kommen kann. Wozu daher Casten?
Wenn es möglich ist, in SVG ein foreignObject einzubetten, dann muss
dies ebenfalls in Form eines SVGElements geschehen. Dann gibt es eben
ein von SVGElement abgeleitetes SVGForeignObjectElement, welches als
Proxy für das foreignObject fungiert.
Da ist nichts Geheimnisvolles dabei und es ist seit langem bekannt wie
man solche Dinge löst.
Das Problem ist, dass viele Programmierer, gleich nachdem sie den Cast
entdecken, den für die Lösung aller Probleme halten. Ich sitze auch
gerade an so einem Programm, an dem mein (Anfänger) Vorgänger meinte
alles und jeden umcasten zu müssen. Leider hat er sich dabei ein paar
mal ein absolut notwendiges 'huge' weggecastet. Die Folge sind
sporadische Speicherüberschreiber bzw. Zugriff auf falsche Werte, weil
dann eben manchmal das Segmentregister doch nicht den Inhalt hat, den er
gerne hätte. Das Pikante daran: nimmt man den Cast weg, dann warnt der
Compiler auch brav, dass hier eine Pointerverkürzung statt findet.
Casts sind Waffen! Genauso wie _delay_ms in der AVR Programmierung sind
sie oft nicht die Lösung sondern das Problem. Und genau so muss man sie
dann auch behandeln.
Wenn ein Compiler einen Pointer Datentyp Mismatch anzeigt, dann ist
manchmal ein Cast eine Lösung. Meistens aber nicht.
Karl H. schrieb:> Wenn in einem Programm exzessiv gecastet werden muss, dann ist am Design> was faul!> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts> vor.
Wenn man fremde Libraries (deren APIs grundsätzlich von betrunkenen
Schimpansen entworfen werden) benutzen muss, verschwinden alle guten
Vorsätze und man castet die schöne const-Korrektheit und viele andere
gute Ideen aus dem eigenen Programm weg, damit es compiliert.
Tom schrieb:> Karl H. schrieb:>> Wenn in einem Programm exzessiv gecastet werden muss, dann ist am Design>> was faul!>> In einem gut entworfenem C++ Programm kommen fast keine expliziten Casts>> vor.>> Wenn man fremde Libraries (deren APIs grundsätzlich von betrunkenen> Schimpansen entworfen werden) benutzen muss, verschwinden alle guten> Vorsätze und man castet die schöne const-Korrektheit und viele andere> gute Ideen aus dem eigenen Programm weg, damit es compiliert.
Ich gestehe zu, dass man an Schnittstellen des öfteren nicht umhin
kommt, die Dinge zurecht zu casten. Aber das ist relativ isoliert. Wenn
ich auf einer mittleren Programmebene rumcasten muss wie ein Wilder,
dann ist das praktisch immer ein Hinweis auf einen Designfehler.
Karl H. schrieb:> Wenn> ich auf einer mittleren Programmebene rumcasten muss wie ein Wilder,> dann ist das praktisch immer ein Hinweis auf einen Designfehler.
Dann guck besser mal nicht in die Quellen von Qt rein...