C++ Standard library and exceptions

Started by
13 comments, last by SiCrane 13 years, 6 months ago
In C++ is there any way to easily know which functions or methods in the standard library would throw an exceptions?

I do know that certain functions/methods would obviously throw an exception, e.g push_back,
emplace,
vector::at,
creating a std::string or perhaps mystring = "abcdefg";

is there any place where I can find a comprehensive list

Or would it be better and easier if i just assume that every standard library function and method is capable of throwing exceptions.

regards
Advertisement
Quote:Original post by littlekid
In C++ is there any way to easily know which functions or methods in the standard library would throw an exceptions?


Yes, read the documentation for that function.
Quote:Original post by littlekid
In C++ is there any way to easily know which functions or methods in the standard library would throw an exceptions?


No. Plain and simple.

This is why exception specifications are a poorly thought out misfeature and should be avoided.

Oh, yeah, the exceptions that can be thrown by standard library containers and functions are explicitly documented. Problem is, most of the standard library is container and function templates. That means that, for example, std::vector<T>::push_back(const T&) could very well throw an exception if T::T(const T&) throws or propagates an exception. Same with std::sort(). Same with most standard library containers and functions.

You also need to take into account indirect calls. For example, std::vector<T>::push_back() could throw an out of memory exception, because std::allocator<T> acts as if ::operator new was invoked, and ::operator new is documented as possibly throwing std::bad_alloc.

Some parts of the library, for example IOStreams, may throw exceptions depending on flag settings at runtime.

The standard also does not specify exception safety guarantees, at least up to C++0x. There is general agreement among implementors, but no specification. I believe this has been remedied in C++0x.

Stephen M. Webb
Professional Free Software Developer

ahh thanks for the replies, so I guess i have to just wrap everything in a try/catch block to prevent exception from leaking.

Now after you guys replies, it feels to me that exception seems to make life harder than it was before... :S

regards
There are some functions in the standard library guaranteed not to throw. They're declared with the throw() exception specifier.
Quote:Original post by Bregma
Quote:Original post by littlekid
In C++ is there any way to easily know which functions or methods in the standard library would throw an exceptions?


No. Plain and simple.

This is why exception specifications are a poorly thought out misfeature and should be avoided.


I don't know if I'd go so far as to call them a worthless "misfeature" -- though I'd agree that probably their biggest weakness is a lack of early standard.


Basically there's no way to know which functions might throw, or even what, because you can never really know whether there are underlying dependencies that might themselves throwh, and whether or not the function in question will propagate those exceptions to you.

You can only know for certain which functions will not throw, as SiCrane said; all other functions are suspect.

If you'd like to know more about exceptions, their issues and best practices around them, I'd recommend reading the exceptions chapters (well, the whole book, really) of Scott Meyer's Effective C++ (3rd Ed.) -- probably half the book, directly or indirectly, deals in some way with exceptions.

throw table_exception("(? ???)? ? ???");

I simply assume anything that i didnt write can throw anything (not just an object, but any data type!), unless it has the throw() specification to indicate it clearly can only throw a specific data type or object, or nothing.

When you receive an unhandled unexpected exception you are basically in a situation where you would have to research its meaning before you can handle it safely anyway, so treat it the same as abort(), as your standard library most likely does when you are using debug runtimes.
Quote:Original post by Ravyne
Quote:Original post by Bregma
Quote:Original post by littlekid
In C++ is there any way to easily know which functions or methods in the standard library would throw an exceptions?


No. Plain and simple.

This is why exception specifications are a poorly thought out misfeature and should be avoided.


I don't know if I'd go so far as to call them a worthless "misfeature" -- though I'd agree that probably their biggest weakness is a lack of early standard.


MSVC doesn't even bother implementing them, aside from eliminating handling cruft in the case of nothrow(). Even where implemented, all they add is to allow you to do two things at runtime: Throw a different exception or die horribly (since std::unexpected is not allowed to return). Note well that you can do both of these things just fine without specifiers, with more power and flexibility, by simply using a try/catch expression. There is no compile time enforcement.

There's the tiniest bit of potential rationalization in crashing as soon as possible on account of security or somesuch, but come on, you're using C++. You're already fairly fucked ;)
Quote:Original post by SiCrane
There are some functions in the standard library guaranteed not to throw. They're declared with the throw() exception specifier.

Ah, then you misunderstand throw specifications. That's what makes them a misfeature.

A an empty throw specification does not mean the function does not throw exceptions. It means if an exception is propagated through that function the exception will be lost and exception of type std::unexpected will be thrown.

There is no way in C++ to guarantee a function will not throw or propagate an exception. No way. Without exception.

Your best bet is to just write exception-safe code. It's not hard, and it tends to result in better code.

Stephen M. Webb
Professional Free Software Developer

If a function that is defined as throw() tries to throw an exception, terminate() is called. An exception is not thrown.

This topic is closed to new replies.

Advertisement