Particularly, do the functions that return NULL pointers in case of errors call the error callback? If that's the case and the error is handled by the callback, there would be no reason to check the return value, right?
The error callback is for diagnostic purposes - not error handling. It is used by the internal function: _glfwInputError in init.c, which is called at various places in the GLFW library. Typically, when something like an unknown or illegal option, attribute or internal error is encountered.
Related
I'm a member of project which uses c++11. I'm not sure when I should use error code for return values. I found RVO in c++ works great even if string and struct data are returned directly. But if I use a return code, I cannot get the benefit of RVO and the code is a little redundant.
So every time I declare function, I couldn't decide which I should use for a return value. How should I keep a consistency of my code? Any advice will help me.
// return string
MyError getString(string& out);
string getString();
// return struct
MyError getStructData(MyStruct& out);
MyStruct getStructData();
Usually, using exceptions instead of error codes is the preferred alternative in C++. This has several reasons:
As you already observed, using error codes as return values prevents you from using the return values for something more "natural"
Global error codes, are not threadsafe and have several other problems
Error codes can be ignored, exceptions can not
Error codes have to be evaluated after every function call that could possibly fail, so you have to litter your code with error handling logic
Exceptions can be thrown and passed several layers up in the call stack without extra handling
Of course there are environments where exceptions are not available, often due to platform restrictions, e.g. in embedded programming. In those cases error codes are the only option.
However, if you use error codes, be consistent with how you pass them. The most appealing use of error codes I have seen that does not occupy the return value spot and is still thread safe was passign a reference to a context object in each and every function. The context object would have global or per-thread information, including error codes for the last functions.
If you have a large system that automatically shows a nice window explaining a caught exception it would be nice to be able to present the error code along with the message (for further investigation). But since some functions calls are to failing windows functions, which set an error code, and some are local failing functions that don't set the error code I wonder if there is a way to check if the last set error code has been "retrieved" already.
Let's say we have a piece of code
if (!CopyFile(("c:\foobar.txt", "d:\foobar.txt",FALSE))
{
throw FooBarException("bla bla bla");
}
Here it would be possible to automatically add the error code to the error message since CopyFile is a function that sets the error code on failure. Now, we could add the error code "manually" within the if statement and append it to the error string passed when creating the exception. But to not have to change thousands of places in existing code we could have the constructor of the FooBarException automatically fetch and append the error code. But this also raises the issue in question.
What if some code that doesn't set the error code causes a FooBarException to be raised. Then the constructor would GetLastError but get an error code that might not be connected to the current exception at all.
But if the constructor of FooBarException could call some LastErrorRetrived (or something similar) and get true if the error code has already been retrieved before it ould ignore appending the error code and assume it's connected to an earlier error.
Now I understand this can go haywire if one does not actually "retrieve" the error code after every windows function that can fail and set the error code. But let's assume this is done.
Short answer: No.
The value returned by GetLastError is simply a global (per-thread) object without any logic attached. It can be accessed through GetLastError, SetLastError and the mysterious RestoreLastError.
I'm afraid I have to break the news: Retrofitting error handling into a system that wasn't prepared for it is tedious.
There is really very little you can do outside of implementing several exception classes (for Win32 error codes, COM HRESULTs, etc.) and changing each and every invocation.
GetLastError() just gets thread's last-error code value and that's all. So, I believe there is no way to know was it called once or a few times. Moreover, I don't really think you need to.
The best solution here is to create WinAPIException class derived from some base class (for example, std::exception ). In constructor WinAPIException should call GetLastError() before any other WinAPI call. It guarantees that the error value isn't change.
if( !CopyFile("c:\foobar.txt", "d:\foobar.txt",FALSE) )
throw WinAPIException("Houston, we have a WINAPI problem");
If you check result after non-WinAPI function call - just use other exception class (derived from the same base class):
if( std::cin.get() < 0 )
throw std::runtime_error("Houston, we have runtime problem");
Thus, you can use single try...catch statement to catch both exceptions:
try {
...
} catch( std::exception &e ) {
...
}
I'm building an error handling mechanism for a C++ application. Right now, I got the windows part done using VectoredExceptionHandling and I wanted to know if there is a similar concept on Solaris. Basically, whenever an exception is thrown from anywhere in the program, I want to have a callback called. Under windows, you can register a callback using AddVectoredExceptionHandler(). How do I do this for Solaris?
Not 100% if this will work, but you can try to mimic the way gdb's catchpoints work: see http://www.delorie.com/gnu/docs/gdb/gdb_31.html The key piece of info is this:
"To stop just before an exception handler is called, you need some knowledge of the implementation. In the case of GNU C++, exceptions are raised by calling a library function named __raise_exception which has the following ANSI C interface:
/* addr is where the exception identifier is stored.
id is the exception identifier. */
void __raise_exception (void **addr, void *id);
To make the debugger catch all exceptions before any stack unwinding takes place, set a breakpoint on __raise_exception"
So, my guess is that you could install your own __raise_exception via LD_PRELOAD trick, for example.
Regarding the terminate handler,
As i understand it, when something bad happens in code, for example when we dont catch an exception,
terminate() is called, which in turn calls abort()
set_terminate(my_function) allows us to get terminate() to call a user specified function my_terminate.
my question is: where do these functions "live" they don't seem to be a part of the language, but work as if they are present in every single cpp file, without having to include any header file.
If there are default handler functions for terminate and abort that you did not install yourself, they'd have to be in the runtime library provided by your compiler.
Normally, every program is linked against the runtime library (e.g. glibc under Linux). Among other reasons, this is because the runtime library contains "hidden" code for essential things, e.g. code that calls your main function at startup.
I don't see why you think there is no need to include a header:
int main() {
abort();
}
gives the following error for me:
error: 'abort' was not declared in this scope
Neither C nor C++ have any "special" functions - if you want to use a function, you must declare it somehow. These two live in the C++ Standard Library, and are declared in cstdlib and exception. Of course, these headers themselves may be #included by other headers, thus making the functions available, but this is not specified by the standard.
set_terminate - terminate handler function
Sets f as the terminate handler function.
A terminate handler function is a function automatically called when the exception handling process has to be abandoned for some reason. This happens when a handler cannot be found for a thrown exception, or for some other exceptional circumstance that makes impossible to continue the handling process.
The terminate handler by default calls cstdlib's abort function
In writing Win32 C++ code, I'd appreciate some hints on how to handle errors of Win32 APIs.
In particular, in case of a failure of a Win32 function call (e.g. MapViewOfFile), is it better to:
use AtlThrowLastWin32
define a Win32Exception class derived from std::exception, with an added HRESULT data member to store the HRESULT corresponding to value returned by GetLastError?
In this latter case, I could use the what() method to return a detailed error string (e.g. "MapViewOfFile call failed in MyClass::DoSomething() method.").
What are the pros and cons of 1 vs. 2?
Is there any other better option that I am missing?
As a side note, if I'd like to localize the component I'm developing, how could I localize the exception what() string? I was thinking of building a table mapping the original English string returned by what() into a Unicode localized error string. Could anyone suggest a better approach?
Thanks much for your insights and suggestions.
AtlThrow isn't terribly useful, it throws CAtlException which merely wraps an error code. Having a MapViewOfFile fail is a truly exceptional problem with a low-level error code that doesn't tell you or your user much at all what actually went wrong. Handling the error is almost always impossible, it isn't likely that you can shrug it off and just not use a MMF. You'll have to log the error and terminate your program with a very generic error.
Getting very detailed in your error message is usually wasted effort. "MapViewOfFile call failed in MyClass::DoSomething() method" just doesn't mean anything at all to your user or her support staff. Great for you though, something to trace the error to. But you can easily automate this, without localization trouble, by using the __FILE__ and __LINE__ macros. All that you really need to match the error to the source code.
Keep the error message short and snappy. For Windows errors, you'll want to use FormatMessage() to let Windows generate the message. It will automatically be localized, the message text is standardized and googles well. Deriving from std::exception is okay. Use string resource IDs for custom messages so you can easily localize them. Solves the what() problem too.
You shouldn't use exceptions for error handling. Exceptions are exceptional. For C++ error handling, look at : System error support in C++0x