开发者

about throw() in C++

voi开发者_如何学JAVAd MyFunction(int i) throw();

it just tells the compiler that the function does not throw any exceptions.

It can't make sure the function throw nothing, is that right?

So what's the use of throw()

Is it redundant? Why this idea is proposed?


First of all, when the compiler works right, it is enforced -- but at run-time, not compile-time.. A function with an empty exception specification will not throw an exception. If something happens that would create an exception escaping from it, will instead call unexpected(), which (in turn) calls abort. You can use set_unexpected to change what gets called, but about all that function is allowed to do is add extra "stuff" (e.g. cleanup) before aborting the program -- it can't return to the original execution path.

That said, at least one major compiler (VC++) parses exception specifications, but does not enforce them, though it can use empty exception specifications to improve optimization a little. In this case, an exception specification that isn't followed can/does result in undefined behavior instead of necessarily aborting the program.


It can't make sure the function throw nothing, is that right?

You are almost there. It is an exception specification. It means that as an implementer you gurantee to your client(s) that this piece of code will not throw an exception. This does not however stop some functions within MyFunction to throw and which, if you do not handle them, will bubble up and cause your/client's program in a way you did not intent it to. It does not even mean that you cannot have a throw expression inside.

It is best to avoid such specification, until and unless you are absolutely sure that your code will never throw -- which is kind of difficult except for very basic functions. See the standard swap, pointer assignments etc.

Is it redundant? Why this idea is proposed?

Not exactly. When properly used, it can be of help to the compiler for optimization purposes. See this article. This article explains the history behind no-throw well.

Digging a bit more I found this excellent article from the Boost documentation. A must read. Read about the exception guarantees part.


As you said, it just tells the compiler that the function does not throw any exceptions.

When the compiler expects possible exceptions, it often has to generate the code in some specific form, which makes it less efficient. It also might have to generate some additional "household" code for the sole purpose of handling exceptions when and if they are thrown.

When you tell the compiler that this function never throws anything, it makes it much easier to the compiler to recognize the situations when all these additional exception-related expenses are completely unnecessary, thus helping the compiler to generate more efficient code.

Note, that if at run time you actually try to throw something out of a function that is declared with throw() specification, the exception will not be allowed to leave the function. Instead a so called unexpected exception handler will be invoked, which by default will terminate the program. So, in that sense it is actually enforced that a throw() function does not throw anything.

P.S. Since exception specifications are mostly affecting the run-time behavior of the program, in general they might not have any compile time effect. However, this specific exception specification - the empty one throw() - is actually recognized by some compilers at compile time and does indeed lead to generation of more efficient code. Some people (me included) hold the opinion that the empty exception specification is the only one that is really worth using in the real-life code.


To be honest exception specifications in the real world have not turned out to be as usfull as envisoned by the origianl designers. Also the differences between C++ runtime checked exception specifications and Java's compile time checked exception specifications has caused a lot of problems.

The currently except norms for exception specifications are:

  • Don't use them.
  • Unless they are the empty form.
    • Make sure that if you use the empty form gurantee that you actually catch all excetions.

The main problem is that if you have a method with a throw spec. Then somthing it uses changes underneath and now throws new types of exception there is no warning or problem with the code. But at runtime if the exception occurs (the new one that is not in throw spec) then your code will terminate(). To me termination is a last resort and should never happen in a well formed program I would much rather unwind the stack all the way back to main with an exception thus allowing a sliughtly cleaner exit.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜