C-Cast vs. C++ Cast
-
Hi,
wenn ich den 4. Parameter auf (void**) caste, geht es einwandfrei:
DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&inputDevice, NULL)Der formale 4. Parameter ist vom Typ LPVOID*.
Wenn ich die selbe Zeile als C++ cast schreibe, gibts nen FehlerFAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, static_cast<void**>(&inputDevice), NULL)Fehler 1 error C2440: 'static_cast': 'LPDIRECTINPUT8 *__w64 ' kann nicht in 'void **' konvertiert werden e:\programmieren\c++\directx 9\environment rendering\oneil scattering\v3\dxapplication.cpp 58
WTF!? Wieso ist das so?
-
Wie wäre es mit der Holzhammer-Methode (reinterpret_cast<>())
-
der c-cast interessiert sich nur mäßig genau für das, was du tust. static_cast hingegen achtet darauf, ob es überhaupt möglich ist und daran scheitert es hier. eine referenz kann man als zeiger interpretieren aber nicht als einen zeiger auf einen zeiger, wie du es getan hast.
-
reinterpret_cast ist nicht die holzhammer methode, sondern die "korrekte". der cast ist nämlich von vornherein nicht besonders toll gewesen

-
portabel wäre:
void* inputDevice_tmp = 0; // oder inputDevice FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, &inputDevice, NULL) inputDevice = static_cast<LPDIRECTINPUT8>(inputDevice_tmp);was passiert mit reinterpret_cast bzw. C-Cast? Das ist äquivalent zu:
DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, &reinterpret_cast<void*&>(inputDevice), NULL)Das heißt, es wird ein Alias vom void* auf den Zeiger inputDevice, der einen anderen Typ hat, benutzt. Das ist in zweierlei Hinsicht problematisch, weshalb eben das Ganze mit static_cast nicht geht:
1. die strikten Aliasregeln von C++ werden gebrochen (was in jedem Falle undefiniertes Verhalten im Sinne das Standards ist) - damit das trotzdem geht, muss der der Compiler explizit diese Form von Aliasing erlauben und damit zurechtkommen; zu beachten ist, dass nicht der Cast an sich undefiniertes Verhalten hat (Alignment ist ja kein Problem wegen 2.), sondern erst der Zugriff über diesen Zeiger auf inputDevice in der Funktion DirectInput8Create.
2. damit das Ganze irgendwie Sinn ergeben kann, muss die Objektrepräsentation beider Zeigertypen identisch sein; das ist bei den Plattformen, die directx kennen, allerdings der Fall.
-
Jetzt mal praktisch gesehen: Ich kann auch einfach den C-Style Cast auf (void**) lassen, oder?
-
BuffCaster schrieb:
Jetzt mal praktisch gesehen: Ich kann auch einfach den C-Style Cast auf (void**) lassen, oder?
Auch wenn ich gleich Haue krieg: Ja

-
Badestrand schrieb:
BuffCaster schrieb:
Jetzt mal praktisch gesehen: Ich kann auch einfach den C-Style Cast auf (void**) lassen, oder?
Auch wenn ich gleich Haue krieg: Ja

Haue bekommst nicht gleich, aber man sollte C-Casts genauso in einer C++-Funktion verwenden wie man jede andere C-Funktion einer aequivalenten C++-Funktion vorziehen sollte: gar nicht. Sicher kannst es machen, es wird auch (leider) noch in den meisten Faellen gemacht, weils weniger zu schreiben ist und den Code nicht so ueberfuellt.
Als kleine Lektuere kann man sich ja mal hier umschauen: http://www.cplusplus.com/doc/tutorial/typecasting.htmlreinterpret_cast ist genauso ein Hammer wie der C-Cast, static_cast und dynamic_cast sind daher sinnvoll, da sie eine gewisse Form der Sicherheitsueberpruefung liefern. Ist also nur eine Frage der Codingstyles. Verboten ists nicht.