Implizite Typkonvertierung - Wozu?



  • Moin, Leutz.
    Ich habe mal eine Frage.

    Bei vielen Api-Funktionen, die eine HBRUSH als Parameter verlangen
    eine HINSTANCE übergeben und mit impliziter Typenkonvertierung
    (HBRUSH). Dabei handelt es sich doch um die selben Datentypen?
    Nur ein anderer typedef halt.

    Ich habe hier einen kleinen source geschrieben, wo meine
    Ausgabefunktion eine myUINT als Parameter verlangt,
    übergebe aber eine unsigned short int ohne implizite
    Typkonvertierung.

    #include <iostream>
    #include <windows.h>
    using namespace std;
    
    typedef unsigned short myUINT;
    
    void printline(myUINT param)
    {
    	cout << param << endl;
    }
    
    int main(int argc, char * argv[])
    {
    	unsigned short int var2 = 2;
    
    	// Keine implizite Typumwandlung nötig!
    	printline(var2);
    
    	// Selber Datentyp, selbe Aufnahmegröße
    	cout << sizeof(HINSTANCE) << endl;
    	cout << sizeof(HBRUSH) << endl;
    
    	system("PAUSE");
    	return 0;
    }
    

    Hier meckert der compiler nicht.
    Meine Frage: Wozu muss implizite Typkonvertierung sein?



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • ähm... war implizite Typkonvertierung nicht eigentlich das, was der Compiler von selber macht?

    das heißt:

    short sNumber = 10;
    int iNumber = sNumber; // implizit
    float fNumber = (float)sNumber; // explizit
    

    und wozu braucht man explizite Konvertierung?

    ich würde meinen, dass man die immer dann braucht, wenn der Compiler sicher sein will,
    dass man auch meint, was mach schreibt,
    denn:

    HBRUSH hBrush = irgendwas; // HBRUSH -> Handle auf einen Brush
    HINSTANCE hInstance = NULL; // HINSTANCE -> Handle auf eine Programminstanz
    // -> beides sind zwar Handles, also müsste der Compiler das implizit machen,
    // ABER:
    // willst du wirklich einen Handle auf einen Brush in einen Handle auf eine Programminstanz casten?
    // schließlich zeigt das Handle dann immer noch auf einen Brush!
    // der Compiler will also sicher sein, dass du nicht ausversehen irgendwelchen Mist eingibst, deshalb:
    hInstance = (HINSTANCE)hBrush;
    // oder noch besser:
    hInstance = reinterpret_cast<HINSTANCE>(hBrush);
    

    außerdem würde ich meinen, dass dieser Thread eher ins C++ oder Ansi C Forum passt.

    MfG DrakoXP



  • Danke, dann wäre ja gleich mehr geklärt als gefragt war.
    // edit: Ah doch, eine hätte ich noch.
    Wie bekomme ich es hin, dass der compiler bei meinem source
    auch ohne die explizite Konvertierung streikt?

    Und wieso stürzt beim Einsatz dieser MessageBox statt der
    erwünschten MessageBox das Programm ab?

    MessageBox(NULL, (char*)IDC_ARROW, "hi", MB_OK);
    

    Ich wollte nur mal sehen, welche Zeichenkette sich hinter der Konstante evrbirgt.
    Ist LPCTSTR und nicht LPSTR oder LPCSTR, aber wenn der compiler schon eine
    Fehlermeldung wirft.

    11 C:\Dokumente und Einstellungen\sjBlack\Desktop\win32 text editor\main.cpp invalid static_cast from type `CHAR*' to type `char'

    bei diesem code

    MessageBox(NULL, static_cast<char>(IDC_ARROW), "hi", MB_OK);
    

    nehme ich doch stark an, dass es sich um einen simplen char pointer handelt. oO



  • Hä???

    IDC_ARROW ist kein String. IDC_ARROW ist ein Murks von Microsoft damit man anstelle von Strings auch gewisse Konstanten übergeben kann. Der "Trick" dabei ist dass diese ganzen Konstanten alle < 2^16 sind, und der Speicher in den 1. 64KB niemals für irgendwas verewendet wird.

    Funktionen wie LoadCursor interpretieren alles < 2^16 als Resource-ID, und alles >= 2^16 als String. Daher geht das mit LoadCursor. Mit AfxMessageBox geht es nicht, weil ... IDC_ARROW eben kein String sondern eine Schummel-Konstante von Microsoft ist.



  • DrakoXP schrieb:

    hInstance = (HINSTANCE)hBrush;
    // oder noch besser:
    hInstance = reinterpret_cast<HINSTANCE>(hBrush);
    

    Um Gottes willen!
    Nimm bitte nicht bedenkenlos reinterpret_cast! Das sollte man nur anwenden wenn es wirklich nichts anders geht. In diesem Beispiel von DrakoXP ist das sogar überflüssig. 😡

    Denn dieses Schlüsselwort hat einen riesigen Nachteil: Damit schaltest Du sämtliche Compiler-Warnungen und Fehlermeldungen aus! Z.B. aus einem Pointer wird eine Zahl usw.

    Ich meine, in mindestens 90% (oder 95%?) der Applikationen braucht man diesen Schlüsselwort nicht. Und häufiges Anwenden führt bekanntlich zu blinder Nachlässigkeit... 👎

    Das hört sich besserwisserisch an, ist aber wirklich so, meint
    Martin



  • -.-'

    hab ich nicht selber gesagt,
    dass man das NUR machen soll,
    WENN man wirklich sicher ist, dass man das auch will?

    hab ich nicht gesagt, dass man das nur tun sollte,
    wenn man ganz genau weiß, was rauskommt?


Anmelden zum Antworten