Rückgabewert beim Aufruf von WinAPI-Funktionen testen



  • Ich habe mir vor vor kurzen das Buch "Microsoft Windows Programmierung für Experten" von Jeffrey Richter gekauft. Darin steht auf Seite 3 für Funktionen die als Rückgabetyp BOOL haben:

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

    Das heißt doch, das man z.B. nicht

    if(GetOpenFileName(&ofn)) { [...] }
    

    schreiben soll, sondern entweder

    if(GetOpenFileName(&ofn) == 0) { [...] }
    

    oder

    if(GetOpenFileName(&ofn) != 0) { [...] }
    

    Hab ich das jetzt nur falsch verstanden, oder hält sich da einfach fast niemand dran 😕



  • Ne, hast du falsch verstanden.

    Bei
    if (bla)
    wird bei Integer Werten geprüft ob der Wert ungleich Null ist (das heißt, true ist so definiert, dass es einen anderen Wert außer 0 hat).

    TRUE hingegen ist 1. Also nicht jeder Wert ungleich 0. Deswegen kannst du if (bla) benutzen, aber nicht if (TRUE == bla). Außer du hast natürlich C++ bool Werte, aber das ist bei der WinAPI ja nicht so.



  • Das sollte doch jedem selbst vorbehalten sein wie er das macht. 🙄



  • Also TRUE ist 1 und true irgendein Wert ungleich 0?!



  • TRUE == true
    FALSE == false



  • 😕



  • Aus meiner WinDef.h:

    #ifndef FALSE
    #define FALSE               0
    #endif
    
    #ifndef TRUE
    #define TRUE                1
    #endif
    

    true und false sind C/C++ und bedeuten IMHO das Gleiche.

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

    So ein Blödsinn.



  • Ich hätte das halt so gedacht:

    Eine Funktion kann auch z.B. 3 zurückliefern, um Erfolg zu melden.

    if(3 == TRUE)  // false
    if(3 == true)  // false
    
    if(3)          // true
    if(3 != FALSE) //true
    if(3 != false) //true
    if(3 == 0)     //false
    if(3 != 0)     //true
    

    Mit einem Vergleich mit true bzw. TRUE kommt halt fälschlicherweise (bzw. hier ungewollt) false



  • Einige Leute sollten erstmal nachdenken bevor sie schreiben!

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

    Das ist völlig korrekt.

    Ich mache es am Beispiel klar:
    Die Funktion (ausgedacht) GetAsyncBuffer gibt bei korrekter Bearbeitung einen Zeiger zurück, welche in unserem Beispiel 0x044CF8D ist. Wenn die Funktion fehl schlägt, gibt sie einen NULL Zeiger zurück (also 0). So, nun zu den Testverfahren:

    // korrekt bearbeitet, Rückgabewert ist 0x044CF8D
    if (TRUE == GetAsyncBuffer())
    {
       // doch leider würde dieser Test behaupten, dass die Funktion
       // fehlgeschlagen ist, da 0x044CF8D ungleich 0x1 ist.
    }
    
       // gleiche Situation
    if (GetAsyncBuffer())
    {
       // richtiges Verhalten, denn hier wird geprüft ob der
       // Rückgabewert wahr ist, und das ist bei allen Werten
       // ungleich 0 der Fall.
    }
    

    Mit true und false könnte ihr das nicht ganz vergleichen, da sie vom ganz anderen Datentyp sind.



  • lol, dummes Beispiel Loggy. *g*
    Die Funktion GetAsyncBuffer würde nie jemand auf TRUE oder FALSE prüfen, weil sie einen SHORT zurückgibt.

    Entweder

    if(GetAsyncBuffer())

    oder

    if(GetAsyncBuffer() != NULL))

    Ich denke mal das ist geschmackssache.



  • 🙂 🙂

    Das mit dem SHORT ist natürlich quatsch. Ich hatte GetAsyncBuffer() in der Hilfe eingegeben und dachte die gibt es tatsächlich, dabei bin ich bei GetAsyncKeyState gelandet.

    Aber trotzdem. Ich habe noch nie jemand gesehen, der auf die Idee gekommen ist, einen Zeigerrückgabewert auf TRUE geprüft hat.



  • 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.


Anmelden zum Antworten