Rückgabewert beim Aufruf von WinAPI-Funktionen testen



  • Die Funktion war ja auch ausgedacht.

    Aber das muss ja nicht nur bei Zeigern so sein. Nehme ich mal ein konkretes Beispiel. Das MSDN sagt zum Rückgabewert der SetTimer Funktion:

    If the function succeeds and the hWnd parameter is not NULL, then the return value is a nonzero integer. An application can pass the value of the nIDTimer parameter to the KillTimer function to destroy the timer.

    If the function fails to create a timer, the return value is zero. To get extended error information, call GetLastError.

    Tests gegen TRUE sind hier völlig nutzlos, da "nonzero integer" nicht 1 sein muss, sondern einfach etwas anderes als 0.



  • Einige Leute hier sollten mal besser lesen, worum es geht.

    Darin steht auf Seite 3 für Funktionen die als Rückgabetyp BOOL haben:

    @Loggy: Keine deiner Beispiel-Funktionen hat diesen Rückgabetyp. Und nochmal:

    Rückgabewerte dieses Typs sollten immer daraufhin überprüft werden, ob sie gleich 0 oder ungleich 0 sind und nicht, ob sie TRUE sind.

    Dieser Satz ist in diesem Zusammenhang völliger Quatsch!



  • ich würde sagen, man sollte es immer so prüfen wie es in der doku steht.



  • Oh, Asche über mein Haupt.

    Es gibt dennoch zwei Gründe die dafür sprechen:

    • Konsistenz: Man sollte alle Funktionen gleich prüfen (was einem vertraut ist sieht man schneller)
    • BOOL ist nur ein typedef von char (oder int, keine Ahnung, jedenfalls ein typedef), der Compiler kann also nicht gegen Bereichsüberschreitungen prüfen. Was machst du mit einer 0x5 in einem BOOL Wert? Ist das TRUE oder FALSE?

    Auch wenn die Notwendigkeit nicht mehr da ist...

    [edit]Habe ich gerade in der MSDN gesehen (für BringWindowToTop, der Return Wert ist als BOOL angegeben):

    Return Values
    If the function succeeds, the return value is nonzero.

    If the function fails, the return value is zero. To get extended error information, call GetLastError.

    Dort steht, dass er nicht 0 ist, jedoch steht da nicht, dass er 1 ist. Ich würde mich also nicht immer drauf verlassen.

    [ Dieser Beitrag wurde am 16.02.2003 um 17:39 Uhr von Loggy editiert. ]



  • So, jetzt habe ich es getestet:

    Die Funktion ShowWindow(hWnd, iCmdShow); gibt bei mir 16 zurück, obwohl als Rückgabewert BOOL angegeben ist (weil das Fenster schon vorher angezeigt war).

    Also nix Quatsch, sondern sogar sehr wichtig!



  • Das steht ja so auch in der Beschreibung:

    If the window was previously visible, the return value is nonzero.

    If the window was previously hidden, the return value is zero.

    Da steht ja nix von TRUE oder FALSE, also testet man es auf 0 oder != 0
    Daran würde ich mich halten.



  • Jo, eben. Aber es ist trotzdem eine BOOL Funktion. MSDN meint:

    [

    BOOL ShowWindow(
      HWND hWnd,     // handle to window
      int nCmdShow   // show state
    );
    


  • Jo, ist für mich unverständlich. Ich weiss nicht warum die sowas gemacht haben. Aber wie immer, hat das bestimmt irgendeinen Sinn, den ich noch nicht erkannt habe. 🙂



  • Ich denke mal undokumentierte Fehlercodes... aber keine Ahnung.



  • @Loggy: Ich gebe mich geschlagen. Du hast recht.



  • Da ich jetzt TOTAL verwirrt bin, stell' ich mal eine Behauptung in den Raum:

    Für C / C++ hat alles, was nicht 0 (inkludiert auch "\0" oder NULL) ist, den Wahrheitswert WAHR. 0, \0 und NULL entsprechend FALSCH.

    Also wird in

    pSonstwas = NULL;
    if(pSonstwas) ...
    

    das if-Statement nicht ausgeführt.

    Dies hat noch gar nix mit Microsoft o.ä. zu tun.

    Jetzt gibt es halt den Typ bool, der in ANSI-C definiert ist (ein int?).
    Und den typdef BOOL, den Microsoft in der Win-API spezifiziert (32 Bit).

    Und da gilt das gleiche: Ist das Dingen als Zahl (Zahlenwert) 0 -> isset FALSCH, ANSONSTEN (!!) WAHR.

    Entsprechend sind (false = FALSE = 0) und (true = TRUE != 0) definiert...

    ??? Sarge



  • TRUE ist aber 1 und nicht "jede Zahl ungelich 0". Das heißt, wenn du

    myvar == TRUE testest, ist das nur Wahr, wenn myvar == 1 ist und nicht, wenn myvar einen wahren Wert hat (also ungleich 0).

    Beispiel:

    int i = 5;
    
    if (i)
    {
      // wird ausgeführt, da i ungleich 0
      // hier wird also geprüft, ob i ungleich 0 ist und nicht ob es 1 ist
    }
    
    // aber:
    if (i == TRUE)
    {
       // wird nicht ausgeführt, da 5 ungleich 1
    }
    
    // und
    if (i == true)
    {
       // wird ausgeführt (wahrscheinlich mit Compilerwarnung)
       // da i erst auf bool gecastet wird und dann mit true verglichen
    }
    

    [ Dieser Beitrag wurde am 18.02.2003 um 16:40 Uhr von Loggy editiert. ]



  • a) man vergleicht nie einen boolschen Wert explizit mit true oder false
    b) bei

    int i = 42;
    if (i == true) ...
    

    wird true in int umgewandelt, nicht i in bool; deshalb ist der Vergleich ebenfalls falsch.



  • Wird da jetzt eigentlich immer der "kleinere" Datentyp für den Vergleich in den größeren umgewandelt, oder immer der rechte in den linken? Kurz: wäre ein Vergleich if (true == i) wahr?



  • immer der kleinere in den größeren und signed in unsigned, unabhängig von der Reihenfolge. Die Regeln stehn detailliert im entsprechenden Standard, aber es läuft auf die einfache Formel hinaus.



  • a) man vergleicht nie einen boolschen Wert explizit mit true oder false

    Das verstehe ich nicht. Wieso sollte man folgendes nicht machen:

    bool b = true;
    
    if (b == true)
    {
       // do...
    }
    


  • das wäre doch nur ein unnötiger (meist nicht erfolderlicher), zusätzlicher Vergleich 🙄



  • Loggy: Warum sollte man? Eine Bedingung gilt als wahr, wenn sie in bool umgewandelt true ist, dh

    if (b)

    ist äquivalent

    if (b == true)

    ist äquivalent

    if ((b == true) == true)

    ist äquivalent

    if (((b == true) == true) == true)

    .. you get the idea 🙂



  • Und bei BOOL also int? Wie sollte man es da machen?



  • BOOL b = some_predicate();

    if (b) ... da BOOL automatisch nach bool umgewandelt wird (0 -> false, alles andere -> true)

    (hier ist wie schon gesagt if (b == TRUE) oder if (b == true) nicht äquivalent)


Anmelden zum Antworten