Zurücksetung des letzten Fehlerwertes durch Exception ( throw GetLastError() )



  • Ich hab neulich bei der Auswertung von error codes durch exceptions ein Verhalten entdeckt, das sich am besten wie folgt zusammenfassen lässt:

    #include <iostream>
    #include <Windows.h>
    #include <cstddef>
    
    int main()
    {
    	try
    	{
    		if(!ReadFile(NULL, NULL, 0, NULL, NULL))
    		{
    			DWORD lasterror = GetLastError();
    			throw lasterror;
    		}
    	}
    	catch(DWORD dw)
    	{
    		std::cerr << dw << std::endl;
    	}
    	std::cin.get();
    }
    

    Gibt den Wert 6 aus, der korrekte Fehlercode für die falsche Nutzung von ReadFile

    #include <iostream>
    #include <Windows.h>
    #include <cstddef>
    
    int main()
    {
    	try
    	{
    		if(!ReadFile(NULL, NULL, 0, NULL, NULL))
    		{
    			throw GetLastError();
    		}
    	}
    	catch(DWORD dw)
    	{
    		std::cerr << dw << std::endl;
    	}
    	std::cin.get();
    }
    

    Gibt den Wert 0 aus, als ob kein Fehler aufgetreten ist, obwohl das ja durch den Kontrollfluss nachweislich der Fall war.

    Für die Beispiele wurde GCC 4.7.2 verwendet mit

    -pedantic -Wall -Wextra -O0 -std=c++11 -ftrapv
    

    Nun ist es einfach, das Problem zu umschiffen, aber meine Frage währe, ob das denn wirklich das vorgesehene Verhalten ist, oder ob GetLastError einfach nicht für die Benutzung in Kombination mit C++ exceptions gedacht ist.



  • Die Frage ist ja: Wann wird der Parameter von "throw" (also "GetLastError") _ausgeführt_ ... ist das im Standard überhaupt explizit definiert?

    Ich vermute, dass dies Compiler-Spezifisch ist, wie dies implementiert ist... und dann GetLastError (bzw. SetLastError) intern bei vielen WinAPI-Aufrufen verwendet wird (acuh von der CRT) ist dies natürlich sehr ungeschickt...



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum WinAPI in das Forum Compiler- und IDE-Forum verschoben.

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

    Dieses Posting wurde automatisch erzeugt.



  • In Ordnung, ich werde mich wohl damit abfinden müssen, dass throw in dieser Implementation intern an dem LastError Wert pfuscht, dann initialisiere ich halt Fehlerwerte vor dem throw Ausdruck. Danke für die Antwort.



  • Ich hab auch noch nie gesehen, dass jemand einen DWORD als throw wirft 😮



  • Das ist nur eine vereinfachte Form, im Originalcode wird mit GetLastError ein Objekt initialisiert, das von std::exception abgeleitet ist und mit FormatMessage den Text für what() erzeugt, es hat aber genau dieselbe Wirkung wie dieses Beispiel. "Die Operation wurde erfolgreich abgeschlossen" (Code 0)



  • Jochen Kalmbach schrieb:

    Ich hab auch noch nie gesehen, dass jemand einen DWORD als throw wirft 😮

    Das mache ich für einfache Fehlerbehandlung auch gerne.


Anmelden zum Antworten