2

Possible Duplicate:
Is there a generally accepted idiom for indicating C++ code can throw exceptions?

How do you indicate in your code when a C++ function is possible to throw something? I don't mean through documentation, but through syntax.

For example I tried placing a throw(std::exception) at the end of the function declaration, but that gave me a warning saying that "C++ exception specification ignored except to indicate a function is not __declspec(nothrow)", which I guess means the compiler ignored the throw and proceeded as if it were not there.

I also tried adding a throw() (without anything in the parenthesis) at the end of the declaration, but — contrary to my expectations — that means the function is expected to never throw anything: "function assumed not to throw an exception but does".

Atm I'm using throw(...) to syntactically indicate the function may throw as this doesn't give me any errors or warnings. Do you have any other suggestions as to how I might indicate this through syntax?

Community
  • 1
  • 1
Paul Manta
  • 30,618
  • 31
  • 128
  • 208

3 Answers3

6

You don't. Exception specifiers do not mean "Here's what I can throw", they mean "if anything other than this gets thrown, go to std::terminate". This behavior is counterintuitive to the point that MSVC++ does not and will not support them.

The semantics of C++ is that you must assume a function can always throw.

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • 1
    No, in case of dynamic exception specification it will go to `std::unexpected`, not `std::terminate`. – Karl von Moor Jun 02 '11 at 15:36
  • @Karl: I was not giving a technical answer there -- the semantics are not necessarily what the standard says. The default behavior of unexpected is to call terminate or abort (don't remember which exactly), so for most users it's going to mean the same thing. The point here is that it's a runtime check, not a compile time check. – Billy ONeal Jun 02 '11 at 15:42
  • I know it's runtime, but I was looking for a way to quickly indicate a function may throw. Even though C++ allows everything to throw unless otherwise specified, the reality is that most of the time functions don't throw. This means cases when they do throw should be made to stand out. – Paul Manta Jun 02 '11 at 15:46
  • 1
    @Paul: In my experience, most functions *do* throw. At least, `std::bad_alloc`. – Billy ONeal Jun 02 '11 at 16:51
  • @Billy I suspect the code that throws `std::bad_alloc` is generated by the compiler... (Just a guess, I don't know what you're referring to.) I was talking about user written code. – Paul Manta Jun 02 '11 at 17:01
  • 1
    @Paul: A function which calls functions that throw, also throws, unless it catches those exceptions. Most of the time someone, somewhere, is calling `std::basic_string::append` (Or the `operator+=` equivelent), `std::vector::push_back`, or something like that. – Billy ONeal Jun 02 '11 at 17:06
2

Most of the compilers are non conforming to the standard when it comes to Exception specifications. Exceptions specifications are considered as an experiment that failed.
For example:
If you have a blank exception specification then what gets called? the unexpected() method or a bad_exception will be thrown and if both in what order?

 #include "stdafx.h"  
 #include <stdio.h>  
 #include <exception>  
 #include <iostream>  


using namespace std;

class A
{
    public:
        int i;
};

void myunexpected () 
{
    cerr << "unexpected called\n";
}

void doSomething(void) throw();
void doSomething(void) throw()
{
    A obj;
    obj.i= 100;
    throw obj;
}


int _tmain(int argc, _TCHAR* argv[])
{
    set_unexpected (myunexpected);
    try 
    {
        doSomething();
    }
    catch (bad_exception be) 
    {
        puts("Caught something");
    }
    catch (A &obj) 
    {
        puts("Caught Integer");
    }
    return 0;
}

If you run this code on Visual studio, you will see that the exception just gets caught by the appropriate handler.

So to conclude, Exception specifications is a failed experiment and it's best to avoid them.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
2

Basically, throw specifiers are worthless, as was discovered after their introduction, unfortunately, and current compilers ignore them. They're deprecated, and quality libraries don't include them. Just don't bother with them. C++0x officially deprecates them, and only has a noexcept keyword.

Puppy
  • 144,682
  • 38
  • 256
  • 465