[Exceptional C++ Style] Item 13: A Pragmatic Look at ExceptionSpecifications

Ric Parkin ric.parkin at ntlworld.com
Tue Dec 7 06:51:26 EST 2004


> > An exception spscification tells the compiler to do a run-time check that
> > guarantees that only exceptions of certain types will be throw. If the
> > guarantee is violated, the function unexpected is called. The
> specification
> > below gurantees that function f will emit only exceptions of type A or B.

Shouldn't that be "and types that can match them". See 15.4/7 and 8
 
Also, there was a typo in the original

int f() throw(A, B) {
   throw;  // unexpected is called
}

That is almost certainly wrong as that syntax is for *rethrowing* an existing exception.

The book uses 

throw C; 

where C is a type unrelated to A or B.


Paul
> This is the bit that surprised me. I thought, previously, that exception
> specifications were enforced at compile time in a similar way to const. This
> belief  inspired by MSVC giving me warnings  in certain conditions. Eg:
> 
> #include <memory>
> 
> void MyFunc() throw()
> {
>      throw std::bad_alloc();
> }
> 
> int main()
> {
>      MyFunc();
>      return 0;
> }
> 
> main.cpp(6) : warning C4297: 'MyFunc' : function assumed not to throw an
> exception but does
>         __declspec(nothrow) or throw() was specified on the function
> 
> I just assumed it wasn't an error due to MSVC inadequacy. It now appears
> that MSVC is inline with the standard and "extra" helpful.

Yup. 15.4/10

Note that it's only a warning, not an error.
 
> I think it would be better if exception specifications were enforced at
> compile time. What do people think?

This is an old chestnut that comes up on the newsgroups regularly.

The quick counter argument is that templates can make things tricky.
 
Also, there's experience that using exception specs is in general a bad idea - it exposes implementation detail in the signature. I understand that unchecked exceptions in the Java world are used to get round these things, which begs the utility of checked ones.


> > - Do not use exception specifications.
> 
> What about swap functions? For example Herbs copy-swap idiom for class
> copy-constructors and assignment operators? Should the swap function there
> be marked with throw()? 

The no-throw spec is one that *may* be worth having as it can enable some optimisations. But in practice it's fraught with danger

And Item #13 does actually have this as a second moral after "Don't use" 

As for your swap example, I've a feeling that 15.4/2 may make it invalid - explicit specifications must have the same exception spec, so you can't do:

template <typename T>
void swap( T& a, T& b ); // general case, may throw

template <>
void swap<MyType>( MyType& a, MyType& b ) throw(); // special case, can't throw

Not certain of this though - any one with a better idea?

> Even as just as documentation to the user for
> reassurance?
 
Documentation can do that too, without the potential for unexpected behaviour.

Ric


-----------------------------------------
Email provided by http://www.ntlhome.com/





More information about the Effective-cpp mailing list