Sign in to follow this  
littlekid

C++ Standard library and exceptions

Recommended Posts

littlekid    229
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

Share this post


Link to post
Share on other sites
Bregma    9214
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.

Share this post


Link to post
Share on other sites
littlekid    229
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

Share this post


Link to post
Share on other sites
SiCrane    11839
There are some functions in the standard library guaranteed not to throw. They're declared with the throw() exception specifier.

Share this post


Link to post
Share on other sites
Ravyne    14300
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.

Share this post


Link to post
Share on other sites
Brain    18906
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.

Share this post


Link to post
Share on other sites
MaulingMonkey    1730
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 ;)

Share this post


Link to post
Share on other sites
Bregma    9214
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.

Share this post


Link to post
Share on other sites
SiCrane    11839
If a function that is defined as throw() tries to throw an exception, terminate() is called. An exception is not thrown.

Share this post


Link to post
Share on other sites
Shinkage    595
Actually, you're both technically wrong :P

Throwing an exception in a function specified as throw() will call std::unexpected (a function, not an exception type). By default, that handler just calls terminate, but it doesn't have to. It may also throw an exception.

Of course, MSVC ignores this and just makes throwing from a throw() function undefined behavior.

Share this post


Link to post
Share on other sites
littlekid    229
All this really makes throwing exception a big headache, will it be more elegant and well defined in the C++0x standard, like it becomes clearer and more enforced over which functions/members throws or does not throw?

regards

Share this post


Link to post
Share on other sites
SiCrane    11839
Quote:
Original post by Shinkage
It may also throw an exception.

And if it throws an exception, and it doesn't match the exception specification, which is impossible for a throw() function, terminate() is called.

Share this post


Link to post
Share on other sites
Shinkage    595
Quote:
Original post by SiCrane
Quote:
Original post by Shinkage
It may also throw an exception.

And if it throws an exception, and it doesn't match the exception specification, which is impossible for a throw() function, terminate() is called.


Yes, but it's also possible for it to do none of the above... although I can't imagine when you'd actually want that. I guess the moral of the story is, don't count on throw() enforcing any kind of reliable behavior.

EDIT: Actually, now I can imagine--it may call exit() or abort() instead!

Share this post


Link to post
Share on other sites
SiCrane    11839
unexpected may not return and if it throws an exception when handling a throw() function, terminate() is called. Whatever you want to call it, the program must stop executing.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this