Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » casting

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
04.10.2008, 19:19 Uhr
~ull
Gast


Hallo,


C++:
static unsigned long long int seed = 4284567975ULL;
    const unsigned int value = static_cast<unsigned int>((279470273ULL * seed) % 4294967291ULL);


Zu diesem Codestück hätte ich mal zwei Fragen:

1) Wo ist denn überhaupt, der Unterschied zwischen static_cast und nem normalen (unsigned int)bla; ?

2) Was genau passiert denn eigentlich in der zweiten Zeile? Die unsigned long longs sind ja für den unsigned int viel zu groß. Wird dann also schon die Rechnung abgeschnitten oder wird das Zwischenergebnis von zb. 279470273ULL * seed irgendwo zwischengespeichert und dann erst an den uint zugewiesen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.10.2008, 21:56 Uhr
~helfer
Gast


1)

ein static_cast ist sicherer. wenn die typen nicht kompatibel zueinander sind, gibts ein kompilerfehler. der C-cast wandelt einfach um ohne auf die typen zu achten.
außerdem ist er auffälliger im code, damit man genau sieht wo gecastet wird.

2)

nein da die rechnung in der klammer stattfindet wird erst das ergebniss abgeschnitten
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
07.10.2008, 17:07 Uhr
~ull
Gast


Also 2) hab ich mir jetzt mal im Debugger angeschaut und am Ende hat value den Wert 1605071448, was genau dem Ergebnis der Operation (279470273ULL * seed) % 4294967291ULL) entspricht. Das sollte dann aber eigentlich nicht sein, weil zwischenzeitlich mit (279470273ULL * seed) ein Wert entsteht, der viel größer als ein unsigned int ist. Also muss für den doch irgendwo noch genug Platz sein...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.10.2008, 18:15 Uhr
0xdeadbeef
Gott
(Operator)


Klammersetzung beachten - der static_cast castet das Ergebnis der Modulo-Rechnung nach unsigned int, nicht (279470273ULL * seed). Da 4294967291 = 2³² - 5 < 2^³² ist, passt das in einen vorzeichenlosen 32-bit-Integer, was unsigned int auf heute gängigen Plattformen mindestens ist.

Ansonsten, zum einen ist ein static_cast in seiner Syntax eindeutiger - static_cast<foo>(bar) + baz ist deutlich klarer als (foo) bar + baz - wird da jetzt bar gecastet oder bar + baz? Zum anderen (und viel wichtigeren) kann static_cast keine cv-Qualifier wegcasten, was ihn wesentlich ungefährlicher als die alten C-Casts macht.

Anzumerken ist außerdem, dass static_cast keinerlei Laufzeit-Überprüfung vornimmt, im Gegensatz zu dynamic_cast, welcher dazu gedacht ist, eine Basisklassenreferenz (oder -Zeiger) in eine abgeleitete Klasse umzucasten, und vorher überprüft, ob du überhaupt in den richtigen Typ castest (Allerdings ist das Verlangen, dynamic_cast zu benutzen, in der Regel ein Zeichen für Designfehler). Eine Übersicht über die verschiedenen Casts findest du hier.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
09.10.2008, 17:16 Uhr
~ull
Gast


Danke!

Ich hab nochmal eine etwas andere Frage, die aber immernoch zum Thema casting passt


C++:
uint j = static_cast<uint>(result.length() - 2);


result ist ein std::string und uint ein typedef für einen unsigned int. Dient diese Anweisung dann nur dem Leser oder hat das einen tieferen Sinn, weil length() liefert ja einen size_t zurück, was ja auch nur ein typedef für unsigned int ist, also wird hier im Prinzip unsigned int nach unsigned int gecastet...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
09.10.2008, 17:46 Uhr
0xdeadbeef
Gott
(Operator)


Da wird int nach unsigned int gecastet. Stell dir vor, result.length() ist 0 oder 1.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
09.10.2008, 20:39 Uhr
~ull
Gast


ahja, das hab ich bei der Aufregung glatt übersehen...

D.h. (result.length() - 2) wird dabei vorher implizit nach int gecastet?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
15.10.2008, 00:17 Uhr
~ull
Gast


Was ich auch übersehen habe, ist, dass result.length() hier immer mindestens 2 ist, da der Fall <= 1 vorher in einer if-Anweisung abgefragt wird. Ist der cast jetzt überflüssig?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
15.10.2008, 19:16 Uhr
0xdeadbeef
Gott
(Operator)


1. result.length() - 2 ist typischerweise ein unsigned long, nach Integer-Beförderungsregeln. Implizit gecastet wird da gar nichts.

2. Du kannst das den Compiler auch implizit casten lassen, wenn du weißt, dass es passt. Wenn du nicht weißt, dass es passt, kriegst du da ggf. sowieso Probleme - der Cast ist also nicht wirklich nötig, das ist richtig.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: