Related
Hopefully there is a simple answer to this as it seems a simple question, however I have not been able to find any information on this on the interwebs.
In the following code snippet, Visual Studio complains of unreachable code at the line "delete bytes;"
try
{
memcpy(bytes, other.bytes, count);
}
catch (...)
{
delete[] bytes;
throw;
}
Does memcpy not throw exceptions?
No. memcpy is a C function. It doesn't know about C++ features such as exceptions. (Of course, it's perfectly legal to use it in C++, although arguably not the best idea).
In response to karlphillip: I must indeed clarify my thoughts: in C++, memcpy should be used only for low-level buffer copies inside object private implementation. It shouldn't be used as mundanely as it was in C (for example to copy numbers arrays) because plain-vanilla buffers are now usually hidden inside class implementations. Classes that wrap arrays or other large amount of data (such as std::array) expose methods to manipulate their contents. And by the time I write this, Mark Ransom nicely summarized it ;-)
Your catch block catches C++ exceptions. On your platform, memcpy is not defined to throw C++ exceptions, and your compiler knows it, so it correctly informs you that your catch block will never execute.
It's allowed for memcpy to throw C++ exceptions. The function's behavior is undefined for cases when either of the pointers doesn't point at a valid object. It's perfectly valid for the function to throw a C++ exception in that situation because undefined behavior means it's perfectly valid for it to do anything.
You might find that memcpy on your platform throws OS exceptions when you're reading or writing invalid memory. You could get an access violation, but the C++ catch block doesn't catch that kind of exception. Use __try and __except for that. Better yet, analyze and edit your program to make sure you never get into such a situation in the first place. Then you don't have to worry about how any particular platform behaves.
No, memcpy does not throw exceptions.
memcpy comes from C, which predates C++ exceptions, so no. You will never catch an exception that is thrown as a result of memcpy.
I have a little function (in a DLL) which looks like this:
int my_function(const char* const s)
{
try {
return my_object->do_something_with(s);
} catch (exception& e) {
return ERROR_CODE;
}
}
I thought that the try-catch block would prevent anything which might happen inside my_object from propagating to the outside. Unfortunately, I was wrong, and my program which calls this function (from VB) just stopped working because I had passed a null pointer argument.
So, why is my try-catch block not working as (I) expected? Is there a workaround? I used to program a lot in Java and I think it would have worked there ...
It would have worked in Java, because in Java a NullPointerException is thown. In C++, there's no such ubiquitous exception, dereferencing a null pointer will just give a segmentation fault.
Additionally, in C++ there is no enforced exception type hierarchy. An exception of any type may be thrown; exceptions don't have to derive from std::exception. (So even if someone had defined a class NullPointerException {};, but had not designated it to derive from std::exception, you still wouldn't be catching it.)
Dereferencing a null pointer in C++ is undefined behavior. This means the C++ standard doesn't put any limits on what may happen. Anything is permitted - a particular implementation might document its own behavior, or it might not. If it doesn't, the behavior might be consistent and predictable, or it might not.
In general it's best to assume that undefined behavior will cause your computer to catch fire (or format the hard disk). Just don't provoke it. Of course it's difficult to avoid errors in the first cut of your code, so when you do it by accident and your computer doesn't catch fire, then you were lucky, fix the bug and move on. Your function could be rewritten:
int my_function(const char* const s)
{
if (s == 0) return ERROR_CODE;
return my_object->do_something_with(s);
}
Alternatively you could fix the caller to not pass a null pointer in the first place, or you could fix do_something_with to accept a null pointer. C++ functions with pointer parameters should document whether or not null pointers are permitted.
Different people will write the test (s==0) differently - it could be (s==NULL) or (NULL==s) or (!s). Pick one you like.
In practice of course, compilers have good reasons not to set your computer on fire, and modern OSes try to ensure that badly-behaved apps don't massively inconvenience other apps. So on most systems, most of the time, when you dereference a null pointer you'll get some kind of hardware exception or signal, or your process will be killed, or perhaps on an embedded system the device will lock up and need a reboot.
You will not in general get a C++-style software exception that you can catch with any kind of catch clause, although Windows does have a feature called SEH which you can use to get that behavior.
In C++, anything can be thrown, and that anything does not necessarily derive from std::exception, which I'm assuming you're catching (using namespace std?).
If you want to catch everything that can possibly be thrown, you can use a catch-all, catch (...). This will catch any exception, but you won't know what the exception it caught is. It's always better to catch specific exceptions, where possible.
Note that normally, a catch all will not handle lower level exceptions such as access violations. If you're using Windows and Visual Studio, you can configure your project to make catch-all blocks handle these exceptions with /EHa, but doing this is often dangerous and not suggested.
c++ faq items regarding exceptions might help you understand c++ exceptions better.
Lots of people programming in java have a problem understanding pointers and references, so if the program stopped working, maybe it was due to a crash (segmentation fault due to dereferencing NULL?)
There is no NullPointerException in C++. If you really want to catch such an access, you must catch some signals (SIGSEGFAULT for example).
Take it with a grain of salt because I haven't touched a C++ compiler since 1999. So much has changed with the STL and C++ that maybe things have changed. However, this is what I recall.
The exception model in C++ is very different from the one in Java. You have to be a lot, lot, but lot more proactive in checking for errors (and in throwing your own custom exceptions).
In Java, a call to de-reference a reference is ultimately a bytecode instruction sent and interpreted by the JVM. The JVM always check (internally) if the reference is null , and when it finds that it is, it automatically throws a java.lang.NullPointerException.
If the JVM weren't programmed to do such a thing, an access to a null reference would cause the JVM to crash with a SEGFAULT - exactly the behavior one would expect with a compiled, unguarded language when encountering an unguarded null pointer de-referencing (not just C or C++ but also in Pascal, Ada, Assembly or even good old BASIC attempting to do a PEEK/POKE at an invalid address location.)
The way (at least in my time) in C++ (or in any of the languages I've mentioned) was to explicitly check if the pointer (or the address being assigned to a reference) was null. At that point, if the test returns true, you launch your exception. You don't blindly go after the pointer. You gotta explicitly test it for null (or have a very strongly guaranteed pre-condition that the pointer actually points to the thing you need to get access to) before de-referencing.
This is somewhat equivalent to the following Java pseudocode
if( myPossiblyBadReference == null )
{
throw java.lang.NullPointerException( "you suck!" );
// or throw my.own.NPEException(); // preferably a specialization of NullPointerException
}
else
{
doYourThingieWith( myPossiblyBadReference );
}
Things might be done differently now in C++, specially now with the C++0x stuff coming down the pipe (of which I have no clue about.) But at least, that's the behavior I had to deal with when coding in C++.
In other words, there is a lot more elbow grease involved in getting such things done. Remember that you are working at a lower level of abstraction from the one provided by the JVM.
The JVM is a barrier that gives you a lot of nice error-handling capabilities (one which we Java developers tend to rely too much on.) Those error-handling capabilities need to be explicitly be coded when you work at a lower level (not just in C++.)
One is to use C++ exceptions: try catch blocks. But freeing dynamic memory will be an issue when an exception is raised.
Second is to use C style: errno variable
Third is just to return -1 on error and 0 on success :)
Which way should be chosen for a mid-size project and why? Any other better approach..?
But freeing dynamic memory will be an issue when an exception is raised.
No it's not. std::vector<int> v(100); Done.
The concept here is called Scope-Bound Resource Management (SBRM), also known by the much more common (and awkward) name Resource Acquisition Is Initialization (RAII). Basically, all resources are contained in some object which will clean up the resource in the destructor (which is always guaranteed to be run for an automatically allocated object). So whether or not the function exists normally or via exception, the destructor is run and your resource is cleaned up.
Never do an allocation where you need to free it explicitly, use containers and smart pointers.
Second is to use C style: errno variable
Third is just to return -1 on error and 0 on success :)
And how do they help solving your problem of freeing dynamic memory? They also use an early-exit strategy, same as throw.
So in summary, they don’t have an advantage over C++ exceptions (according to you).
In the first place, you should strive for a program with minimum error cases. (Because errors are not cool.)
Exceptions are a nice tool but should be used conservatively: reserve them for "exceptional cases", do not use them to control the flow of your program.
For example, do not use exceptions to test whether a user input is correct or not. (For such a case, return an error code.)
One is to use C++ exceptions: try
catch blocks. But freeing dynamic
memory will be an issue when an
exception is raised.
#see RAII.
Exceptions should be your preferred method of dealing with exceptional runtime situations like running out of memory. Note that something like std::map::find doesn't throw (and it shouldn't) because it's not necessarily an error or particularly exceptional case to search for a key that doesn't exist: the function can inform the client whether or not the key exists. It's not like a violation of a pre-condition or post-condition like requiring a file to exist for a program to operate correctly and finding that the file isn't there.
The beauty of exception-handling, if you do it correctly (again, #see RAII), is that it avoids the need to litter error-handling code throughout your system.
Let's consider a case where function A calls function B which calls C then D and so on, all the way up to 'Z'. Z is the only function that can throw, and A is the only one interested in recovering from an error (A is the entry point for a high-level operation, e.g., like loading an image). If you stick to RAII which will be helpful for more than exception-handling, then you only need to put a line of code in Z to throw an exception and a little try/catch block in A to catch the exception and, say, display an error message to the user.
Unfortunately a lot of people don't adhere to RAII as strictly as they should in practice, so a lot of real world code has more try/catch blocks than should be necessary to deal with manual resource cleanup (which shouldn't have to be manual). Nevertheless, this is the ideal you should strive to achieve in your code, and it's more practical if it's a mid-sized project. Likewise, in real world scenarios, people often ignore error codes returned by functions. if you're going to put the extra mile in favor of robustness, you might as well start with RAII because that will help your application regardless of whether you use exception handling or error code handling.
There is a caveat: you should not throw exceptions across module boundaries. If you do, you should consider a hybrid between error codes (as in returning error codes, not using a global error status like errno) and exceptions.
It is worth noting that if you use operator new in your code without specifying nothrow everywhere, ex:
int* p = new int(123); // can throw std::bad_alloc
int* p = new(std::nothrow) int(123); // returns a null pointer on failure
... then you already need to catch and handle bad_alloc exceptions in your code for it to be robust against out of memory exceptions.
Have a look at this comment by Herb Sutter on try catch for C++ GOTW. And do go through his whole set of articles. He does have a lot to say on when and how to check and save yourself from error conditions and how to handle them in the best ways possible.
Throw an exception. Destructors of variables are always called when an exception is thrown, and if your stack-based variables don't clean up after themselves (if for example you used a raw pointer when you need to delete the result), then you get what you deserve. Use smart pointers, no memory leaks.
But freeing dynamic memory will be an issue when an exception is raised.
Freeing memory (or any other resource for that matter) doesn't suddenly become a non-issue because you don't use exceptions. The techniques that make dealing with these problems while exceptions can be thrown easy, also make it easier when there can be "error conditions".
Exceptions are good for passing control from one context to another.
You let the compiler do the work of unrolling the stack between the contexts then in the new context compensate for the exception (and then hopefully continue).
If your error happens and can be corrected in the same context then error codes are a good method to do error handling and clean up (Don't take this to mean you should not be using RAII you still need that). But for example within a class an error occurs in a function and the calling function can correct for that type of error (then it probably is not an exceptional circumstance so no exceptions) then error code are useful.
You should not use error codes when you have to pass information out of a library or sub system as you are then relying on the developer using the code to actually check and handle the code to make sure it works correctly and more often than not they will ignore error codes.
What techniques can I use to avoid exceptions in C++, as mentioned in Google's style guide?
Don't throw exceptions.
Don't use STL (which relies heavily on exceptions).
Use only new(std::nothrow) or override ::operator new to return 0 on failure.
Note that by avoiding exceptions, you're effectively throwing out lots of useful libraries, including Boost. Basically, you'll have to program everything from scratch.
Not throwing exceptions in your own code is relatively easy: you just don't use the throw statement.
Not throwing exceptions from memory allocation failures is a little more painful: either you don't use normal new (use new(std::nothrow) or malloc or something instead), or you use some nonstandard compiler option to get it to do something nonstandard when it fails (e.g. immediately terminate your program, or return 0), or you override operator new to do something nonstandard when it fails.
If your chosen approach is to immediately terminate the program, you can implement this with set_new_handler(), which I had forgotten about until litb reminded me.
That leaves the problem of dealing with exceptions generated by C++ libraries you don't maintain. Generally you'll have to wrap library calls in a wrapper that looks something like this:
int DoSomething(int &output, const int input) throw() {
try {
output = library_do_something(input);
return 1;
} catch (...) {
return 0;
}
}
The catch (...) catches all possible C++ exceptions from library_do_something (as well as the assignment operator on output, which isn't relevant here), throws away all the information they may have contained, and then maps all those failures to 0.
Note that this style means that you can't use RAII at all, not even a little bit, because you have no way of signaling failure within a constructor. The whole point of RAII is that you acquire all your resources inside of constructors so that they will be properly released by a destructor during exception propagation. But resource acquisition is something that can essentially always fail. So you can't do that inside a constructor.
I'm interested to know why one would want to avoid exceptions in C++ and what mechanism one would replace them with to deal with the reality of unexpected failure while still maintaining decent structure.
Sure adding them to a existing codebase that doesn't use RAII type semantics is extremely costly - but if one is doing green field development then what alternative would you suggest and how are going to justify not using high quality libraries that do use exceptions vs. writing your own exception free / bug free alternatives?
The style guide says they "don't use exceptions" which is just that - they don't throw them and don't call anything that could throw them (for example, they would use the new(std::nothrow) instead of usual new because the latter will throw bad_alloc when it fails to allocate memory.
In some compilers, you may be able to turn off exception handling. This could cause unexpected results with external code though - it is not something I would want to try.
Other than that, the obvious first step would be to avoid throwing exceptions from your own code, probably with liberal use of the nothrow directive, and attempt to avoid throwing exceptions from external (3rd party) code through defensive programming.
That means that your code needs to be aware of possible external exceptional failure conditions all the time, such as running out of memory, out of disk space, loss of an internet connection, hardware failure, and any number of other circumstances that might cause code to throw...
In some cases you may be able to use exception-free versions of some code (such as throwing-new vs. non-throwing new).
What I do is to never throw exceptions with my own code, and to "translate" or wrap any external code that does that.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
There are lots of places where guidelines for designing exception classes can be found. Almost everywhere I look, there's this list of things exception objects should never do, which impacts the design of those classes.
For instance, the Boost people recommend that the class contain no std::string members, because their constructor could throw, which would cause the run-time to terminate the program immediately.
Now, it seems to me that this is rather theoretical. If std::string's constructor throws, it's either a bug (I passed a null-pointer in) or an out-of-memory condition (correct me if I'm wrong here). Since I'm on a desktop, I just pretend I have an infinite amount of memory, and running out of memory is fatal to my application no matter what.
With that in mind, why shouldn't I embed std::string objects in my exception classes? In fact, why couldn't my exception classes be full-featured, and also take care of logging, stack tracing, etc. I'm aware of the one-responsibility principle, and it seems to me to be a fair trade-off to have the exception class do all that. Surely, if my parser needs to report a syntax error, an full-featured exception would be more helpful than an exception built around a statically allocated character array.
So: lean C++ exception classes - how big a deal is it in the real-world? What are the trade-offs? Are there good discussions on the topic?
You could use the Boost.Exception library to help define your exception hierarchy.
The Boost.Exception library supports the:
transporting of arbitrary data to the
catch site, which is otherwise tricky
due to the no-throw requirements
(15.5.1) for exception types.
The limitations of the framework will provide you with reasonably defined design parameters.
Boost.Exception
See also: Boost.System
As a general case, exception classes should be simple, self-sufficient structures and never allocate memory (like std::string does). The first reason is that allocations or other complex operations may fail or have side effects. The other reason is that exception objects are passed by value and thus are stack-allocated, so they must be as light-weighted as possible. Higher level features should be handled by the client code, not the exception class itself (unless for debugging purpose).
The number one job of an exception, well before any consideration to allowing code to handle the exception, is to be able to report to the user and/or dev exactly what went wrong. An exception class that cannot report OOM but just crashes the program without providing any clue to why it crashed is not worth much. OOM is getting pretty common these days, 32-bit virtual memory is running out of gas.
The trouble with adding a lot of helper methods to an exception class is that it will force you into a class hierarchy that you don't necessarily want or need. Deriving from std::exception is now required so you can do something with std::bad_alloc. You'll run into trouble when you use a library that has exception classes that don't derive from std::exception.
Have a look at the std exceptions they all use std::string internally.
(Or should I say my g++ implementation does, I am sure the standard is silent on the issue)
/** Runtime errors represent problems outside the scope of a program;
* they cannot be easily predicted and can generally only be caught as
* the program executes.
* #brief One of two subclasses of exception.
*/
class runtime_error : public exception
{
string _M_msg;
public:
/** Takes a character string describing the error. */
explicit runtime_error(const string& __arg);
virtual ~runtime_error() throw();
/** Returns a C-style character string describing the general cause of
* the current error (the same string passed to the ctor). */
virtual const char* what() const throw();
};
I usually derive my exceptions from runtime_error (or one of the other standard exceptions).
Since I'm on a desktop, I just pretend I have an infinite amount of memory, and running out of memory is fatal to my application no matter what.
So when your app fatally fails, wouldn't you prefer it to terminate cleanly? Let destructors run, file buffers or logs to be flushed, maybe even display an error message (or even better, a bug reporting screen) to the user?
With that in mind, why shouldn't I embed std::string objects in my exception classes? In fact, why couldn't my exception classes be full-featured, and also take care of logging, stack tracing, etc. I'm aware of the one-responsibility principle, and it seems to me to be a fair trade-off to have the exception class do all that.
Why is that a fair trade-off? Why is it a trade-off at all? A trade-off implies that you make some concessions to the Single-Responsibility Principle , but as far as I can see, you don't do that. You simply say "my exception should do everything". That's hardly a trade-off.
As always with the SRP, the answer should be obvious: What do you gain by making the exception class do everything? Why can't the logger be a separate class? Why does it have to be performed by the exception? Shouldn't it be handled by the exception handler? You may also want to localization, and provide syntax error messages in different languages. So your exception class should, while being constructed, go out and read external resource files, looking for the correct localized strings? Which of course means another potential source of errors (if the string can't be found), adds more complexity to the exception, and requires the exception to know otherwise irrelevant information (which language and locale settings the user uses). And the formatted error message may depend on how it is being shown. Perhaps it should be formatted differently when logged, when shown in a message box, or when printed to stdout. More problems for the exception class to deal with. And more things that can go wrong, more code where errors can occur.
The more your exception tries to do, the more things can go wrong. If it tries to log, then what happens if you run out of disk space? Perhaps you also assume infinite disk space, and just ignore that if and when it happens, you'll be throwing away all the error information?
What if you don't have write permission to the log file?
From experience, I have to say that there are few things more annoying than not getting any information about the error that just occurred, because an error occurred. If your error handling can't handle that errors occur, it isn't really error handling. If you exception class can't handle being created and thrown without causing more exceptions, what is the point?
Normally, the reason for the SRP is that the more complexity you add to a class, the harder it is to ensure correctness, and to understand the code. That still applies to exception classes, but you also get a second concern: The more complexity you add to the exception class, the more opportunities there are for errors to occur. And generally, you don't want errors to occur while throwing an exception. You're already in the middle of handling another error, after all.
However, the rule that "an exception class should not contain a std::string isn't quite the same as "an exception class is not allowed to allocate memory". std::exception does the latter. It stores a C-style string after all. Boost just says not to store objects which may throw exceptions. So if you allocate memory, you just have to be able to handle the case where allocation fails.
Surely, if my parser needs to report a syntax error, an full-featured exception would be more helpful than an exception built around a statically allocated character array.
Says the person who just said he didn't mind the app just terminating with no feedback to the user if an error occurred. ;)
Yes, your exception should contain all the data you need to produce a friendly, readable error message. In the case of a parser, I'd say that would have to be something like:
Input file name (or a handle or pointer which allows us to fetch the filename when needed)
The line number at which the error occurred
Perhaps the position on the line
The type of syntax error that occurred.
Based on this information, you can when handling the error produce a nice friendly, robust error message for the user. You can even localize it if you like. You can localize it when you handle the exception.
Generally, exception classes are for use by the programmer. They should not contain or construct text aimed at the user. That can be complex to create correctly, and should be done when handling the error.
The C++ standard requires that exceptions have no-throw copy costructor. If you have a std::string member, you don't have a no-throw copy constructor. If the system fails to copy your exception, it'll terminate your program.
It is also a good idea to use virtual inheritance in designing your exception type hierarchy, as explained in http://www.boost.org/doc/libs/release/libs/exception/doc/using_virtual_inheritance_in_exception_types.html.
However, there is no requirement that exception objects be simple or not allocate memory. In fact, exception objects themselves are typically allocated on the heap, so the system may run out of memory in an attempt to throw an exception.
I think refusing to use std::string in exception classes is unnecessary purism. Yes, it can throw. So what? If your implementation of std::string throws for reasons other than running out of memory just because you're constructing a message "Unable to parse file Foo", then there is something wrong with the implementation, not with your code.
As for running out of memory, you have this problem even when you construct an exception which takes no string arguments. Adding 20 bytes of helpful error message is unlikely to make or break things. In a desktop app, most OOM errors happen when you try to allocate 20 GB of memory by mistake, not because you've been happily running at 99.9999% capacity and something tipped you over the top.
... running out of memory is fatal to my application no matter what.
Unfortunately this is exactly what most people say because they don't want to deal with the complexity that arises otherwise. On the other hand, if you do follow the requirements set by the standard, you get much more robust software that can recover even in low-memory conditions.
Leaving mars rovers aside, think of such a simple case like writing a text processor. You want to implement a copy/paste feature. The user selects some text and hits Ctrl+C. What outcome you prefer: a crash or a message "Not enough memory"? (If there was no enough memory to show the message box just nothing happens.) The second scenario is no doubt much more user friendly, she can just close some other app and continue working on her document.
In fact it's not so hard to guarantee the no-throw copy constructor. You should just store a shared pointer inside your exception that points to the dynamically allocated memory:
class my_exception : virtual public std::exception {
public:
// public interface...
private:
shared_ptr<internal> representation;
};
Assuming that exceptions are for exceptional situations, the atomic count overhead is negligible. In fact this is what Boost.Exception does.
With that said, I recommend jalf's answer as well.