2012-12-06 9 views
8

Ich schreibe mehr und mehr C-Anwendungen, und jetzt frage ich mich etwas über Guss. In C++ ist ein dynamischer Cast ein sehr kostspieliger Vorgang (zum Beispiel ein Downcast), aber ich weiß es nicht einmal für einen statischen.Was macht ein C-Cast wirklich?

In C, hatte ich so etwas zu schreiben:

assert (p); /* p is void* */ 
int v = *(int*)p; 

Ist es ein «C dynamische Guss»? Ist es das gleiche wie die static_cast<int*>(p) von C++? Wie viel kostet es?

Vielen Dank im Voraus.

+2

... für geeignete Definitionen von "sehr" ... – DevSolar

+0

Mögliche Duplikate von [Wie gehen C/C++ - Compiler mit Typumwandlung zwischen Typen mit unterschiedlichen Wertebereichen um?] (https://stackoverflow.com/questions/340413/how-do-cc-compiler-handle-type-casting-between-types-with-different-value-ra) – jww

Antwort

7

Ein Cast in C ist nur zur Kompilierzeit sinnvoll, da es dem Compiler mitteilt, wie Sie ein Stück Daten bearbeiten möchten. Es ändert den tatsächlichen Wert der Daten nicht. Beispiel: (int*)p weist den Compiler an, als Speicheradresse für eine ganze Zahl zu behandeln. Dies kostet jedoch zur Laufzeit nichts, der Prozessor behandelt die Rohdaten nur so, wie sie ihm gegeben werden.

+8

Dies ist nicht für alle Abgüsse korrekt. '(float) 0.3' ändert den Wert auf IEEE754-Systemen. Es ist nicht mehr gleich "0,3". –

+0

Das stimmt, danke. – jazzbassrob

8

Ein C-Cast eines Zeigers ist eher wie ein C++ reinterpret_cast. Es weist den Compiler an, eine Variable als einen anderen Typ zu behandeln und kostet zur Laufzeit nichts.

+1

Es ist, wenn von einem Zeigertyp zu ein anderes, aber in diesem Fall macht ein 'reininterpret_cast' dasselbe wie ein' static_cast'. Casting, sagen wir, ein Double zu einem Integer funktioniert wirklich und ist nichts wie ein 'reininterpret_cast'. Für mich erscheint der Vergleich mit 'static_cast' viel passender als' dynamic_cast'. – sepp2k

+0

@ sepp2k Ich habe meine Antwort aktualisiert, um Ihren Punkt über die Umwandlung von Zeigertypen aufzunehmen. Ich bin mir nicht sicher, ob ich Ihnen zustimme, dass statische und neuinterpretierte Umwandlungen für Zeigertypen identisch sind - überprüft der Compiler nicht, dass statische Umwandlungen zwischen kompatiblen Typen liegen? (Dies geht möglicherweise über eine Tangente hinaus ... Ich stimme deinem Hauptpunkt zu und habe es bemerkt) – simonc

+0

Sie haben recht, 'static_cast' ist nur identisch mit' reininterpret_cast' ** wenn ** es kompiliert. – sepp2k

2

Zeiger sind Zeiger - einen Zeiger zu werfen ist ein Noop.

Es war eine Speicheradresse vor, es ist eine Speicheradresse danach.

Es ist im Wesentlichen eine Aussage "lass uns davon ausgehen,, dass dies ein Zeiger auf Typ X für zukünftige Typprüfung ist".

So könnte man dies eine reinterpret_cast in Bezug auf C++ nennen, wie es keine zusätzliche Kompilierzeit Typ überprüfen, dass z. dynamic_cast oder ein static_cast tut.

Ich glaube nicht, C hat Äquivalente von dynamic_cast ("Runtime-Typ hier überprüfen") oder static_cast ("Führen Sie zusätzliche Kompilierzeit Typprüfungen hier").

Beachten Sie, dass für Nicht-Zeiger Dinge etwas anders verhalten werden.

int b = 1; 
double a = (double) b; 

ist nicht so sehr ein gegossenes, aber eine explizite Typ Umwandlung.

+0

Beachten Sie, dass der Standard ausdrücklich das Recht vorbehält, Zeiger auf verschiedene Typen mit unterschiedlicher Breite zu haben ... Während dies in der heutigen Welt der 8-Bit-Zweierkomplement-IEEE-Floatarchitekturen ein exotischer Fall ist, könnten die Sprachanwälte hinter Ihnen her sein für die Bemerkung "Noop". ;-) – DevSolar

+0

Ok, hab es. Also ist es eher ein _compiler_ ** Hinweis ** als alles andere? – phaazon

+0

Nicht wirklich ein "Hinweis" auf den Compiler: - Es hilft dem Compiler nichts zu optimieren. Aber es ist eine * Programmierer * Sache. Ich lasse den Compiler nicht * raten *, das ist richtig, aber ich * sage explizit aus, dass dies umgesetzt werden sollte, und ist kein Tippfehler; es teilt dem Compiler lediglich mit, dass dies "kein Fehler ist, sondern so gemeint ist". –

5

Ein C-Guss ist mehr wie alle C++ - Gussmodelle außerdynamic_cast kombiniert. Wenn Sie also einen Int-Wert in einen anderen Integer-Typ umwandeln, lautet er static_cast. Wenn Sie Zeiger auf andere Zeigertypen oder Integertypen oder umgekehrt umwandeln, ist dies reinterpret_cast. Wenn Sie eine const wegwerfen, ist es const_cast.

C hat nichts Ähnliches wie dynamic_cast, da es Konzept von Objekttypen hat und für sie wie C++ keine Verwendung haben würde (keine virtuellen Funktionen ...). Typen in Bezug auf die Interpretation der Bits eines Objekts werden nur dann wichtig, wenn sie mit Objekten, die sich auf Objekte beziehen, in C kombiniert werden. Die Objekte selbst haben keine Typen.