I would like to have the constructor abort object construction whenever it encounters certain error code (e.g. if the following is encountered):
CudaObj::CudaObj(InsertionSim *theSim)
{
// Setup
if(cublasInit() == CUBLAS_STATUS_NOT_INITIALIZED) {
printf("CUBLAS init error.\n");
return -1; // abort here rather than return a value
}
...
}
What would be the easiest way for this to be accomplished? Would it be exception handling?
I think the idiomatic way is to throw an exception from the constructor to emphasize that the object is not in a valid state.
Exception handling would definitely be my choice, especially in the case shown above, which really is an exception to the proper flow of the program. Alternatively, you could let the constructor return, and have a function 'IsInitilized()' or some such which would allow you/the user to verify it was completed appropriately. This however does impose an additional burden on the user of your class, that being said you might as well go with exception handling as it is a well-accepted way of imposing this burden (they have to catch the exception).
If you'd rather not use exceptions (although admittedly, I do in this situation), you could make a static method of the class in which you ask "Can I construct an object with these parameters?" and require that that method be called before you construct. So effectively, your constructor would become
CudaObj::CudaObj(InsertionSim *theSim)
{
// Setup
ASSERT(cublasInit() == CUBLAS_STATUS_NOT_INITIALIZED)
...
}
And then you'd need
BOOL CudaObj::CanConstruct(InsertionSim *theSim)
{
// Check if we can construct
return TRUE; // Or FALSE
}
So your code would be
if (CudaObj::CanConstruct(pSim))
{
pObj = new CudaObj(pSim);
}
else
{
// Handle invalid parameter
...
}
You could also provide a convenience method to do both (using OUT arguments, for instance).
Use an exception, unless you have some reason that you aren't using exceptions in your program. The reason is that by using an exception, you prevent the constructor of the object from EVER thinking the object is valid.
Your other choices are to have an 'IsInitialized' method (which will return false if the constructor failed), or a trivial (empty) constructor, and a separate 'Initialize' method, which can return an error code. These strategies are good ones if you are avoiding exceptions, and may be useful in situations where you are incorporating C++ code into older C code.
While I prefer exceptions unless I have a VERY good reason not to, exceptions may have some drawbacks. This article lists some of the drawbacks and several alternatives to exception handling.
Even if you use only exceptions for your error handling, I still recommend reading it.
One other thing: IMO you should not limit your considerations to constructor errors. maintaining two different error handling infrastructures in one system is hard and error prone. Try to select an error handling method for the whole system.
although constructor error handling is a big factor in this decision making, it is not the only one.
Related
I'm writing a Matrice class (for practice sake) and when I wrote the method to multiply two Matrice objects I had to check if certain conditions are met for matrix multiplication:
Matrix Matrix::mul(const Matrix &mat)
{
if(col != mat.row)
//we cannot multiply in this case
else
{
//create temp object result
//perform multiplication
return result;
}
}
Now I'm curious on what to do if the condition hasn't been met because back in main.cpp I'd write something like this:
Matrix a = b.mul(c);
Now what if b and c cannot be multiplied, what should I return?
Is the best way to throw an exception, to just force the person using that class to send compatible matrices, is there another better way?
Don't return anything, throw an exception instead:
if (failure)
throw std::runtime_error("Exception!!");
You can throw any of the different exceptions that suits your case more.
By the way, you could take a look at my project called Matrix on GitHub for an example of how one could create such a class to operate on matrices.
To deal with preconditions you can
Throw an exception.
Return a C++17 std::optional, or boost::optional.
Call std::terminate.
Broken preconditions usually mean that the logic in the calling code is erroneous. One common approach is therefore to just assert the preconditions and test extensively. Ideally that will ensure that the preconditions are never broken.
To help the calling code, it can be a good idea to provide it with at least one way to check whether the call would fail.
What are the possible approaches ?
return some neutral value that shows there is a problem (e.g. an empty matrix)
handle the error, but only while debugging: e.g. use assert() to verifiy and document pre- and post-conditions as well as invariants.
throw an exception to notify that there's a problem: let the caller (or the caller of the caller) decide what to do. If the exception isn't catch , the code will abort. The nice thing is that you can provide additional error information.
Which one should you choose ?
Solution (1) should be used if the error situation is frequent (almost normal) and the function is called often. I wouldn't advise you to use it here.
Solution (2) could be used if the error condition is not expected to happen, and you have confidence that the error situation is prevented (e.g. the user interface would prevent such errors to happen).
Solution (3) is for when the error situation is not really expected and could not really be prevented. According to me, this should be a good candidate solution for your matrix multiplication.
Example for solution 3:
Instead of using a general purpose exception or creating your own specific one, you could use domain_error (domain in the mathematical sense, i.e. the argument is a valid value, but the function is not defined for that value) or invalid_argument:
// in your multiplication
...
if(col != mat.row)
throw std::invalid_argument ("Matrix multiplication operand of incompatible size");
...
// In the calling program:
...
try {
a = b.mul(c);
}
catch (std::invalid_argument &e) {
cout << "Invalid argument provided: " << e.what()<<endl;
}
what should I return?
It depends on your requirements.
Is the best way to throw an exception
It could be. That depends on your requirements.
You have a few options:
Terminate the process. A developer can analyse the core dump to figure out what happened. The advantage of this is that a bug is hard to miss.
Don't even test preconditions within the function. Simply state the preconditions. If the caller violates the preconditions, the behaviour is undefined. This is the most efficient solution but relies on the user of the function to use it correctly.
Test the condition with assert. If the test fails, the process is terminated. Assertions are disabled with NDEBUG macro, so you can disable the check for optimal performance. This allows picking 1. or 2. depending on debug vs release build so is more flexible than either.
Throw an exception. This allows the caller to ignore the possibility of a failure if it cannot be handled, and let code higher in the call stack deal with it... or let the process terminate if it cannot be handled.
Return std::optional. This allows the caller to check if there is a return value and decide which of 1...4 option they wish to use to handle a missing one. If the caller ignores the possibility of non-existing return value, then it defaults to 2. (undefined behaviour).
In short, is it possible to get C++ to force the invoker of a method to put a try...catch block?
(To clarify:
I don't necessarily mean the immediate invoker, I mean forcing the fact that it's caught somewhere. Also, I'm talking about forcing at compile time.)
The long:
I've read that it not recommended to use exception specification and that it doesn't work properly anyway (http://4thmouse.com/mystuff/articles/UsingExceptionsEffectively.html)
But the general consensus seems to favor the use of exceptions to return errors over the user of writing methods that return error codes.
So if I'm writing say a library, what's to stop the user from calling my method without putting any try...catch blocks, and then getting his program crashing when my code throws an exception?
(To be clear, I only require the exception to be caught somewhere in the users stack, not necessarily in the immediate calling code, and the compiler to complain if this is not the case.)
No, it is not.
Indeed, there is no mechanism to force the caller of a function (anywhere in the call stack) to handle any kind of error. At least, not via a compilation failure. Return values can be discarded. Even bundling error codes with return values (via expected<T, E>) doesn't issue a compile-time error if the user doesn't actually check to see if the value is available before fetching it.
C++17 may give us the [[nodiscard]] attribute, which allows compilers to issue a warning if a return value (presumably an error code) is discarded by the caller. But a compile-time warning will be as close as you can get.
In short, is it possible to get C++ to force the invoker of a method
to put a try...catch block?
No. This would defeat the whole purpose of exceptions. Exceptions are specifically made for the use case of propagating errors across multiple layers without the intermediate layers being aware of them.
Let's say you have a call hierarchy like A -> B -> C -> D -> E, and an error occurs in E. A can handle the error. B, C and D do not need to be aware of the error at all. This is exactly what exceptions are good for!
If you want to return an error directly to the caller because handling the error is indeed the caller's concern, then an exception is often the wrong design and a return value might be the better choice.
"Enforced" exceptions of a certain form have been tried in Java, but I'd consider it a failed experiment, as it usually results in code like this:
try {
method();
} catch (SomeCheckedException ex) {
// ignore
}
That C++ does not encourage this should be considered a feature.
I've read that it not recommended to use exception specification and
that it doesn't work properly anyway
Exactly. The only exception specification which was ever useful and which worked was throw() to signal that no exception at all is thrown, and that one has been superseded in C++11 by noexcept.
But the general consensus seems to favor the use of exceptions to
return errors over the user of writing methods that return error
codes.
See above. It depends on whether you want an error to propagate or if the caller can and should handle it.
So if I'm writing say a library, what's to stop the user from calling
my method without putting any try...catch blocks, and then getting his
program crashing when my code throws an exception?
A library which requires its user to surround all function calls with try blocks has a bad interface and should be redesigned, accordingly.
Also... you assume that a "program" will use your library. But this assumption will not always be true. The library client may itself be a library. There may be a lot of different library layers between the program and your library. You use exceptions if you do not care which layer handles them.
There's a general consensus? Not that I'm aware of. As for the exceptions, no. The compiler cannot enforce that somebody catches the exception somewhere up the call stack. At compile time, the compiler has no idea who may be calling your function, and your function may throw any arbitrary exception, as may any function that your function calls. The linker might have a chance, but it would have to maintain a lot of extra information dealing with what exceptions a function may throw, as well as what exceptions a function may catch. This gets even uglier when you start to talk about dynamically loaded libraries (DLL/.so) as that would have to get resolved at runtime.
Suppose you are presented with the following code:
blah & Foo::foo() {
if (_x) { return _blah;}
throw exception("blah error");
}
As far as I can tell, the only way to call this is in a try/catch block as so
try {
blah &b=_foo.foo();
catch(...) {}
Now b is out of scope, making error handling somewhat difficult. One can assign it to a pointer, and then reassign the pointer to a reference below, but that seems rather difficult.
I don't recall an explicit suggestion to avoid creating functions that return references or throw exceptions, but is there a standard way to get around this issue when dealing with these kinds of interfaces?
There seems to be a misconception in your side. If the function above throws an exception, it does not complete and it does not yield a reference. The reference inside the try/catch block is not just inaccessible but it never even existed.
A function that throws an exception does not return.
As chris already mentioned in his comment, you do treat exceptions different from return codes in the sense that you don't wrap every function call that might throw in its own try/catch handler.
Instead of checking for exceptions like you would for return codes (after every function call) you push the exception handling up to the layer that's best equipped to handle the failure that's signaled by the exception. That one might well be several layers up from your current code.
As to returning references, there are a couple of guidelines like not returning references to local objects. In your case it looks like you might be returning a reference to a member, which is probably OK as long as you make sure that you don't run into object lifetime issues.
Something like a C++1y optional might help here. I have seen a proposal for expected<T,Otherwise> as well. You bundle the call into a pseudo-union with either the reference or error information. You handle the error whenever you want, and otherwise access the data if you have checked for lack of error.
This leads to traditional in-line error handling, instead of exception-based 'come-from' error handling, which some prefer.
Well, the trick is to design your exceptions, exception handlers, and error handlers so that you do not run into situations like this. For example, you could enclose all operations that rely on foo()'s successful return in a try block, which allows you to handle exceptions thrown by any of those operations all in once place. Conceptually, you are "trying" to perform the entire task, rather than trying to perform individual steps independently, e.g.:
try {
blah &b = _foo.foo();
b.dehydrate();
_foo.reconceptualize(b);
idealize(b, _foo, "grumble");
} catch (const exception &x) {
// log/handle error
}
Another way to think about it is, if the validity of the reference b depends on the success of foo(), there is only really one place in your code where b is valid, and that's in the try block after foo() is called. Once you leave the try block, there could be no guarantee on the validity of b since at that point the exception may or may not have occurred.
try {
blah &b = _foo.foo();
// <- [1] this is the only point that we *know* foo() returned something valid
} catch (...) {
// <- [2] here we *know* it didn't
}
// <- [3] here we don't know either way
Now if you had code that relied on foo()s success and bs validity, and you had to choose location 1, 2, or 3 above, which seems the most appropriate to you (hint: 1)?
Even if you used a pointer declared before the try block, it's fairly redundant to use e.g. NULL to indicate that an exception was thrown, when you already had that information available previously:
blah *b;
try {
b = _foo.fooptr();
// <- here we know an error did not occur
} catch (...) {
// <- here we know an error occurred
b = NULL; // <- so why do this...
}
// ... when we already had a perfectly good opportunity to handle above;
// we've kind of missed the boat at this point.
That's not to say there aren't cases where the pointer example isn't useful. Perhaps you don't care to do any special error handling or you are abstracting some API behind something else:
void * getData () {
void *data = NULL;
try {
data = getFromThingThatMayThrow();
} catch (...) {
// we really don't care why it failed, and it's more convenient to
// swallow it and return NULL instead.
}
return data;
}
But the take home point is, if you find your exception handling getting really weird and messy like in your example, you may be going down the wrong path, and you should consider stepping back and reassessing your error handling. Exceptions, when used appropriately, can greatly simplify error handling and recovery.
I mean, I knew all the language rules about throw, try {} catch {}, but I am not sure if I am using them correctly in the real world. Please see the following example:
We have a large piece of scientific code which did all sorts of image processing things, recently we decided to spruce it up and make it more robust. One of the routines which is frequently used is void rotate_in_place(float* image, image_size sz);
To make it more robust, we add some sanity check at the beginning of the code:
void rotate_in_place(float* image, image_size sz) {
// rotate_in_place does not support non-square image;
if (sz.nx != sz.ny) throw NonSquareImageError;
// rotate_in_place does not support image too small or too large
if (sz.nx <= 2 || sz.nx > 1024) throw WrongImageSizeError;
// Real rode here
.....
}
Now the problem is that rotate_in_place() is used in over 1000 places, shall I wrap each call of rotate_in_place() with try{} catch {}, this looks to me will make code incredibly bloated. Another possibility is do not wrap any try{} catch{} and let the program exit, but how is this different from just using
if (sz.nx != sz.ny) {
cerr << "Error: non-squared image error!\n";
exit(0);
}
In short, I am not so sure about the real benefit of using throw, try, catch, any good suggestions?
Every site that handles the error needs try-catch block. It all depends on your design, but I doubt you need to handle the error in every rotate_in_place call-site, you probably get away from propagating upwards most of the time.
Printing the error and using exit is bad for three reasons:
You can't handle the error. exit is not handling (unless it's done when the error is absolutely critical, but your function cannot know that — caller might have a way to recover).
You're extending responsibilities of the function with writing to a hard-coded stream, which might not even be available (this is rotate_in_place, not rotate_in_place_and_print_errors_and_kill_the_program_if_something_is_wrong) — this hurts reusability.
You lose all debugging information with this approach (you can generate stack traces from unhandled exceptions, you can't do anything with a function that bails out every time — unhandled exception is a bug, but it's a bug you can follow to the source).
The general rule for exceptions is, "Does the immediate call site care about what's going on here?" If the call site does care, then returning a status code probably makes sense. Otherwise, throwing makes more sense.
Consider it this way -- sure, your rotate in place method has a couple of invalid argument types, in which case you should probably throw std::invalid_argument. It's unlikely that a caller of rotate_in_place wants to deal with or knows how to deal with the case that an image was not square, for example, and therefore that's probably better expressed as an exception.
Another possibility is do not wrap any try{} catch{} and let the
program exit, but how is this different from just using
if (sz.nx != sz.ny) {
cerr << "Error: non-squared image error!\n";
exit(0);
}
It's different because if someone later wants to take your function and put it in, say, a GUI application, they don't have to terminate the program based on the error. They can turn that exception into something pretty for the user or something like that.
It also has benefits for you right now -- namely that you don't have to pull <iostream> into that translation unit simply to do error writing.
I usually use a pattern something like this:
int realEntryPoint()
{
//Program goes here
}
int main()
{
//Allow the debugger to get the exception if this is a debug binary
#ifdef NDEBUG
try
#endif
{
return realEntryPoint();
}
#ifdef NDEBUG
catch (std::exception& ex)
{
std::cerr << "An exception was thrown: " << ex.what() << std::endl;
}
#endif
}
Now the problem is that rotate_in_place() is used in over 1000 places, shall I wrap each call of rotate_in_place() with try{} catch {}, this looks to me will make code incredibly bloated.
It will, and it beats the purpose of using exceptions in the first place.
Another possibility is do not wrap any try{} catch{} and let the program exit, but how is this different from just using [...]
That you can always change the location of exception handling later on. If at some point you find a better place to sensibly handle the error (perhaps recovering from it), then that's the point where you put the catch. Sometimes that's in the very function where you throw the exception; sometimes it's way up in the call chain.
Do put a catch-all in main, just in case. Deriving exceptions from standard ones such as std::runtime_error makes doing this a lot easier.
The point in using exception handling holds in following simple rules:
As soon as anything bad can happen due to bad user input (internal logic should be handled via assertions/logging), throw an exception. Throw as soon as possible, and as much as possible: C++ exceptions are usually pretty cheap compared to say, .Net ones.
Let an exception propagate if you can't handle the error. This means pretty much always.
The thing to remember is: The exception should bubble up to the point where it can be handled. This can mean a dialog box with some formatting of the error, or this can imply that some unimportant piece of logic won't be executed after all, etc.
Using exceptions allows the caller to decide how to handle an error. If you called exit directly within the function, then the program would exit without the caller being able to decide how to handle the error. Also, with exit, stack objects would not be unwound. :-(
What you can do is to make rotate_in_place return a boolean if the function call was succesfull. And return the rotated image via a function parameter.
bool rotate_in_place(float* image, image_size sz, float** rotated_image) {
// rotate_in_place does not support non-square image;
if (sz.nx != sz.ny) return false;
// rotate_in_place does not support image too small or too large
if (sz.nx <= 2 || sz.nx > 1024) return false;
// Real rode here
.....
return true;
}
It depends.
Exceptions are generally meant to be caught/handled. In your case, is it possible to handle the exception (for instance, the user provides a non-square image, so you ask them to try again). However if there is nothing you can do about it, then cerr is the way to go.
Well, I agree that really using Exceptions results in bloated code. That is the main reason for me not liking them.
Anyway, as to your example: The key difference between throwing exceptions and just using exit() is that, since the handling of the exception happens (or is supposed to happen) outside of the program fragment that generated the error/exception, you do not specify how the user of a function/class has to handle the error. By using exceptions you allow different treatments like aborting the program, reporting errors or even recovering from certain errors.
TLDNR: If you use exceptions, the exception-generating part of the code does not need to specify how the exceptional case is treated. That happens in the outside program and can be changed depending on how the code is being used.
I've got this constructor which throws an exception
GenericSocket::GenericSocket(const string& hostname,
const string& servname):
_hostname(hostname),
_servname(servname)
{
initHints();
int rv;
if((rv = getaddrinfo(_hostname.c_str(),
_servname.c_str(),
&_hints,
&_servinfo)) != 0) {
throw GenericSocketException();
}
}
initHints() does a memset of _hints and sets some variables.
I test it with the google test framework like this:
TEST(CreateObject2, getaddrinfoException)
{
mgs_addrinfo_return = 1;
ASSERT_THROW(new GenericSocket("testhost", "4242"), GenericSocketException);
}
The test fails with a core dump:
[ RUN ] CreateObject2.getaddrinfoException
socket creation failed
terminate called after throwing an instance of 'common::GenericSocketException'
what(): Socket creation failed
[1] 43360 abort (core dumped) ./bin/test_common
Besides the fact that I dont know exactly what goes wrong, I suspect some uninitialised object gets deleted(?), a lot seems to happen under the hood, so I started to wonder if it is good practice to throw an exception in a constructor. Is it maybe better to put this functionality in another function which I can call after the creation of the object, and handle the exception afterwards?
IMHO, throwing an exception in a constructor is the best way to handle a situation like this - do you really want a usable object if there is no socket? it doesn't make sense to me. If it's failing to resolve that address, there's a reason for that and that is worthy of an exception (as long as you handle it correctly!)
In your particular case, you should test the return value and make the exception more useful... (for example, HostNotFound - which I'd guess is the case here)
Yes it is. You actually have no choice: constructors have no return values.
But take care of exception safety. See http://www.drdobbs.com/184403429 for instance, or google "strong exception guarantee". Indeed, an object whose constructor has thrown will not be destructed (it has never existed) and must be left in a state which doesn't leak resources.
Of course, the only reasonable thing to do when you can't construct an object is to throw exception, otherwise you would end up with some zombie objects. And answering your other question, no, you can't destroy an object that wasn't created.
Yes, throwing an exception is the most direct way to report that the constructor encountered problems, since they do not return values.
Destructors, on the other hand, should not throw exceptions, since they will be called in the stack unwinding phase of exception handling, and throwing another exception at this point would result in an abort.
There are already at least two discussions about this on SO. On both throwing exceptions from constructors and two-phase initialization:
1) When is it right for a constructor to throw an exception?
2) Throwing exceptions from constructors
If you learn at construction that you won't be able to create a valid object then throwing an exception is arguably your best option. The user of the class is thus forbidden from carrying on in case of error, unless they can handle it. That's usually the correct behaviour of a program.
function()
{
// 1. acquire resources.
// 2. perform action.
// 3. release resources.
}
If you can't fulfil step one then the other steps are futile. That's what we use RAII for: we acquire all the resources we need first, somewhat analogous to the old C style of programming with respect to stack variables. With RAII if any of the resources fail to acquire -- via an exception in the constructor -- then all previously acquired resources will release automatically and the second step will never be attempted. All done behind the scenes, automatically, but this assumes you throw an exception in the constructor if you can't create the object. It also assumes the destructor will do the clean-up.
struct Connection {
Connection() {
if( ! connect() ) throw ConnectionError();
}
~Connection() { // may not throw under any circumstances
try { disconnect(); }
catch( ... ) { }
}
void send(const std::string& message);
// ...
private:
bool connect();
// ...
};
void post(const std::string& message)
{
// step one is easy for the user:
Connection c;
// step two is the bulk of the work:
c.send("HELO");
// step three is automatically done for the user.
}