i am reading this page http://www.cplusplus.com/doc/tutorial/exceptions.html
it says if i write function() throw(); no exceptions can be thrown in that function. I tried in msvc 2005 writing throw(), throw(int), throw() and nothing at all. each had the exact same results. Nothing. I threw int, char*, another type and it was all caught the same way. It looks like throw doesnt affect it at all. What does function() throw() actually do?
See this article for details on C++ exception specifications and Microsoft's implementation:
Microsoft Visual C++ 7.1 ignores exception specifications unless they are empty. Empty exception specifications are equivalent to __declspec(nothrow), and they can help the compiler to reduce code size.
[...] If it sees an empty exception specification, it will assume you know what you are doing and optimize away the mechanics for dealing with exceptions. If your function throws anyway - well, shame on you. Use this feature only if you are 100% positive your function does not throw and never will.
What you're finding is that that version of VC++ didn't enforce specification exceptions. I believe that was documented as a variance from the standard.
However, exception specifications are usually not a good idea. If a program violates them in a standards-conforming implementation (which the VC++ from VS 2005 was not in this case), the system is supposed to catch it. This means that the specification is not a compiler optimization hint, but rather forces the compiler to go to extra lengths, and sometimes produce suboptimal code.
See the Boost rationale for reasons why the highly regarded Boost project does not use exception specifications. This is Boost, which is something of the poster child for doing weird and useful things with advanced parts of the language.
Quoting from A Pragmatic Look at Exception Specifications:
(Mis)understandings
The second issue has to do with
knowing what you’re getting. As many
notable persons, including the authors
of the Boost exception specification
rationale, have put it,
programmers tend to use exception
specifications as though they behaved
the way the programmer would like,
instead of the way they actually do
behave.
Here’s what many people think that
exception specifications do:
Guarantee that functions will only throw listed exceptions (possibly
none).
Enable compiler optimizations based on the knowledge that only listed
exceptions (possibly none) will be
thrown.
The above expectations are, again,
deceptively close to being correct.
See the link for the full details.
Throwing an exception is not enough, you need a try {} catch() block to catch exceptions. If you don't catch exceptions, std::terminate() is called and your program exits abruptly. Take some time out and have go at this.
throw specifications are designed for two purposes:
To serve as a contract between interface implemented and interface user - you state which exceptions can be throwned from your method, some people consider it part of an interface. (contract) Ala checked exceptions in Java.
As a way to signal the compiler that it can apply certain optimizations in case no exceptions can be thrown from a method/procedure (setting up exception handling costs something)
Throwing an exception not specified in throw() clause is a mistake, however at no point is the implementation required to verify it for you. In fact it's not even possible to verify, as it includes all the possible exceptions from subroutines your subroutine calls. (possibly from other modules) It is not even possible within a single module, as is easily reduced to a halting problem :)
Related
I would like your help in understanding what are the possible approaches to using/disabling exceptions in C++.
My question is not about what is the best choice but just about what are the possible options and what these options imply.
Currently, the options I can think of are:
Compiling with -fno-exceptions and giving up most std containers (possibly defining internal containers which do not throw, such as suggested in SpiderMonkey Coding_Style)
Just avoiding to throw and catch in own code, but still using std containers which may throw exceptions. Being happy with the fact that, in the case of exceptions, the program may terminate without stack unwinding, and that even RAII handled external resources may be left hanging. (This seems to be Google C++ approach according to answers to this SO question)
No using exceptions but wrapping all in a catch all std::exception try block just to make sure stack is unwound and RAII handles to external resources are released before program is terminated, as for this Cert C++ rule
As above, but also throwing exceptions which will ultimately result in program termination.
Also using catched exceptions and recovering from exceptions.
I would like to know if my understanding of options is correct, and what I might be missing out or understanding wrong.
I would also like to know whether constraints on granting basic exception safety make sense for options 2-4 (where exceptions always ultimately lead to program termination) or if/how exception safety requirement can be relaxed/restricted to specific cases (e.g. handling external resources, files).
Update
Strictly speaking, when you want to disable exceptions only compiling with no exception support is true way to go, so Option 1. Because when you want to disable exceptions you should also not use or even handle them. Raising an exception would terminate or go to a hard faulty on most implementations instantly, and only by this you would avoid overhead implications like space or performance overhead even how small (see below) they are.
However if you just want to know which paradigms about exception usage are out there, your options are almost right, with the general idea you haven't mentioned of keeping exceptions exceptional and doing things that are likely or even just could throw, at program startup.
And even more in general, in comes to error handling in general: Exceptions are there to handle errors which you come across at runtime and if done correctly errors you can ONLY detect at runtime. You can avoid exceptions by simply making sure to resolve all problems you can detect before runtime, like proper coding and review (code time), using strict types and checks (templates , compile time), and rechecking them again (static analyser).
Update 2
If you understand you wrong about caring about exception safety I would say:
Basically at first it depends whenever you enable exceptions in general: If they are disabled you can't and shouldn't care about exception safety since there are none (or if they try to come into existence, you will terminate/crash/hardfault anyway).
If you enable exceptions but don't use them in your code, like in case 2, 4 and 3, no problem you want to terminate anyway, so missing cleanup code is not relevant (and the stuff in 3. gets still run in any case). But then should make it clear to everybody that you don't want to use them, so they won't try to recover from exceptions.
And if you use them in your code, you should care about exception safety in the way, that when an exception gets thrown, you clean up after your self too, and then its up the main handler or future code changes, when ever you still terminate or can recover. Not cleaning up but still using exception wouldn't make sense. Then you can just stick to option 1.
This should be to my knowledge exhaustive. For more information see below.
Recommendation
I recommend option 4. and I tell you why:
Exceptions are a very misunderstood and misused pattern. They are misused for program flow like the languages Java does in a excessive. They are often forbidden in embedded or safety code because of their nature that is hard to tell which handler will catch it, if there is one, and how long this will take, for which the C++ std just says basically "implementation magic".
Background
However in my reasoning the hate for exceptions is basically a big XY problem:
When people are complaining that their recovery is broken and hard to tell, then the usual problem is that the don't see you can't or should do much about the most exceptions, that's what they are for. However things like a timeout or a closed tcp connection are hardly non normal, but many people use exceptions for that, that would be wrong of course. But if your whole OS tells you that there is no network adapter or no more memory what could you do? The only thing you probably want is trying to log the reason somewhere and this should be done in one try/catch around the main block.
The same is for safety/real-time programs: For the example of running out of memory, when that happens you are **** anyway, the strategy then is to do this stuff at an unsafe initialisation time, in which exceptions are no problem too.
When using containers with throwing members its a similar scenario, what would you be able to do when you would get their error code instead? Not much, thats the reason why you would make sure at code time that there is no reason for errors, like making sure that an element is really in there, or reserving capacity for your vectors.
This has the nice benefit of cleaner code, not forgetting to check for errors and no performance penalty, at least using the common C++ implementations like gcc etc.
The reason of 3. is debatable, you could do this in my opinion too, but then my question is: What do you have to do in the destructors which wouldn't cleanup your operating system anyway? The OS would cleanup memory, sockets etc.. If have a freestanding scenario, the question remains, whenever different: You plan to halt because your UART broke for example, what would you like to do before halting? And why can't you do it in the catch block before rethrow?
To sum up
Has the problem of not using any throwing code, and still be left with the problem of how to handle rare error codes. (Thats why so many C programmers still use goto or long jumps)
Not viable IMHO, worst of both
as mentioned ok, but what do you need to do in your static DTors, what you even un-normal termination wouldn't do?
My favourite
Only if you really have rare conditions that you are actual able to recover from
What I mean as a general advice: Raising and exception should mean that something happened that should never happen in normal operation, but happened due to a unforeseeable fault, like hardware fault, detached cables, non found shared libraries, a programming fault you have done, like trying to .at() at an index not in the container, which you could have known of, but the container can not. Then it is only logical that throw an exception should almost every time lead to program termination/hard fault
As a consequence of compiling with exception support, is that for example for a freestanding ARM program, your program size will increase by 27kB, probably none for hosted (Linux/Windows etc.), and 2kB RAM for the freestanding case (see C++ exception handler on gnu arm cortex m4 with freertos )
However you are paying no performance penalty for using exceptions when using common compilers like clang or gcc, when you code runs normal i.e. when your branches/ifs which would trow an exception, are not triggered.
As a reference i.e. proof to my statements I refer to ISO/IEC TR 18015:2006 Technical Report on C++ Performance, with this little excerpt from 7.2.2.3:
Enable exception handling for real-time critical programs only if
exceptions are actually used. A complete analysis must always include
the throwing of an exception, and this analysis will always be
implementation dependent. On the other hand, the requirement to act
within a deterministic time might loosen in the case of an exception
(e.g. there is no need to handle any more input from a device when a
connection has broken down). An overview of alternatives for exception
handling is given in §5.4. But as shown there, all options have their
run-time costs, and throwing exceptions might still be the best way to
deal with exceptional cases. As long as no exceptions are thrown a
long way (i.e. there are only a few nested function calls between the
throw-expression and the handler), it might even reduce run-time
costs.
In the book More Effective C++ (Number 15), I read that code becomes significantly slower if exceptions are enabled, even if they are not used. In my opinion, exceptions are of limited use, and I try to avoid them, but this is another topic.
I do not entirely understand his statement:
What does enabling/disabling exceptions mean? It it the difference between having zero or more than zero try/catch blocks? Is it a compiler flag? What happens if I use a DLL in which exceptions can occur?
Suppose no exception is ever thrown:
Does the code become slower as a whole or are only the parts where the program enters/exits try/catch blocks become slower? According to the author, both is true.
How can I compile without exceptions? Can I do this even if I have try/catch blocks? Can I do this if DLLs I use might throw exceptions?
What does enabling/disabling exceptions mean?
Passing a flag to the compiler which disables standard conformance in relation to exceptions and makes it not generate any exception support.
What happens if I use a DLL in which exceptions can occur?
If some library handles exception internally, nothing. If it lets it escape to the caller (I never saw any library which does that, because of ABI issues, but whatever), your program crashes (in best case) as it cannot handle it. If there is a wrapper for DLL which your code include and which converts error codes to exceptions (common occurence), then it is the same as if you used exceptions in your code.
Does the code become slower as a whole or are only the parts where the program enters/exits try/catch blocks become slower? According to the author, both is true.
Notice that the book you are citing is old. Compilers are evolving. Modern compilers use zero-cost exceptions which do not incure perfomance cost if exception is not thrown. Exception handling does make executable larger as it should generate all data and code needed to process exceptions, but it should not make it slower on non-exceptional path.
How can I compile without exceptions? Can I do this even if I have try/catch blocks?
You do that in compiler-specific way. Consult your compiler documentation. Usually doing so makes compiler reject code containing any exception-related facilities, e.g. point out try as unrecognised identifier.
Here's a not-too-uncommon problem in C++ programming:
Programmer A writes a C++ library (we'll call it Foo), which includes a nice public API that programmer B's program calls methods on, in order to implement part of his program. When working with the Foo API, programmer B looks at the documentation and the header file, but not very much at the .cpp files, mainly because the whole point of having a public API is to hide implementation details. Programmer B gets his program to work and initially everything looks good.
One day the program is doing its thing, when something unusual happens inside the Foo codebase that causes a Foo method to throw an exception. Programmer B was unaware that that type of exception might be thrown by that Foo method, and so the exception either doesn't get caught (and the program crashes), or the exception gets caught by a very general exception handler (e.g. catch(...)) and doesn't get handled adequately (and so the program does something non-optimal, like putting up a dialog with a cryptic error message).
Since I'd like my C++ software to be robust, my question is, what is a good way to avoid a scenario like the above? Requiring programmer B to read through all of the .cpp files in the Foo codebase (and all .cpp files of any C++ codebase that Foo calls, and so on all the way down) looking for throw statements doesn't seem like an adequate solution, since it violates the spirit of encapsulation, and even if it was done there would be no guarantee that more throw statements might not be added in the future. Requiring programmer A to document all possible thrown exceptions seems like a good idea, but in practice programmer A is very likely to miss some of them, especially if his code in turn calls into yet another library that may or may not document 100% of its possible exceptions.
In Java there is some support for automated exception-handling checks; e.g. you can annotate your Java methods to declare what exceptions they might throw, and if the calling code doesn't explicitly handle all of those exceptions (or itself declare that it might throw them), the compile fails and the programmer is forced to fix his program -- thereby preventing the problem scenario described above. C++, on the other hand, has no such compile-time enforcement, meaning that verifying that a C++ program handles all exceptions properly seems to be left entirely up to the programmer and QA team. But in a non-trivial program, actually performing such a verification seems impractical; is there some technique (automated or non-automated) by which C++ programmers can gain confidence that their programs handle all possibly-thrown exceptions in a considered fashion? (Even just a program that would list all of the exceptions that can be thrown from various calls would be useful, I think -- at least then there'd be a list of known possibilities to check the exception-handling code against)
At first take this question seems to present quite a dilemma. Until you discover the following insight.
Where exceptions are concerned, the fact that an exception is thrown, where it is thrown, and where it is caught captures more than 90% of the importance of a thrown exception's information. The type of the exception rarely is that important.
It turns out that we seldom create code that can troubleshoot a problem and come up with a remedial solution. Almost always the only useful thing code can do is report that the command failed and its error message.
If the exceptions used in a library are derived from std::exception and support a useful call to what(), then when you report/log that message, you've moved to capturing 95% of the useful information. If the what() message contains __ FILE __ , __ LINE __ , and __ func __ information, then you are at 98% of the important information provided by most thrown exceptions.
Even if a library isn't carefully documented with each exception type that can be thrown from each particular function call, a decent library will provide the base type used for all the exceptions it with throw (often it will be std::exception or something derived from it). This exception base class will have some way of getting the associated error message (such as the what() call).
But even if you are reduced to using catch (...) as your last line of defense, your error message can still indicate that a command failed and what command it was. And you have the confidence that you are handling every exception that might be thrown.
Can a C++ exception come "out of nowhere"? Not literally. Does anybody know non obvious special cases when C++ runtime can throw exception from a place that is not an explicit call of the function?
Platform specific experiences and information about implementations that deviate from the standard are interesting also.
Please do not post answers about:
Macroprocessor tricks that hide function calls;
Default constructors;
Destructors;
Overloaded operators;
Overloaded conversions;
Unoverloaded operators new and new[];
MSVC provides an option that allows to handle hardware exceptions (GPF, division by zero, etc) as C++ exceptions. Can anybody comment on how this is handled on other platforms or maybe somebody knows a right place in the standard that speaks about this?
To the guy who downvoted this question: Please, have courage to tell what is wrong here.
No, no, and there isn't one, it's only an MSVC option. Only Windows treats hardware errors like exceptions, and these structured exceptions are only converted into C++ exceptions if you ask for it. The other platforms use signals.
Exceptions do not come out of nowhere. They come when you, or the well-defined places in the Standard library (and a couple in the language like dynamic_cast) throw them. The C++ runtime does not throw them for lolsies. If you have an exception of unknown source, then get a better debugger and learn how to use it until it doesn't have an unknown source.
What is a good use case for uncaught_exception?
Herb Sutter seems to give good advice here. He doesn't know of a good use for it and says that some cases where it appears to be useful don't really work.
Probably none
uncaught_exception can be used in destructors, to determine whether they are being executed in the context of an exception (where a throw will terminate the program). I don't disagree that the philosophy is slightly flawed, but it depends on your use of exceptions - if your exception is a recoverable error, it may be more convenient to just try to fix it rather than let another part of the code attempt to deal with it as you normally would.
It is also useful if you have code requiring an active exception (this is rare, but occasionally you have an exception control library that will use throw; to get the current exception, but that will cause a termination if there is none, so uncaught_exception can be used to determine whether that will abort (and if so, possibly throw an exception!). An example is the new exception facilities, which are also a part of boost.