Using noexcept

Hi,
Did you notice the new keyword in incoming C++11 standard (C++0x): noexcept? In case you wonder what it does, why it works the way it does, and how you should use it, I wrote an article about it on my blog. Here is the link:
http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/

Regards,
&rzej
OMG! C++ now doing the same mistake Java did long, long time ago: checked exceptions, only this one is more complex than in any other language. The whole idea that the compiler statically checks what throws exceptions and what not is broken - you can't do it right, and if you try, you get something complex, hard to understand and inconvenient to use.
closed account (S6k9GNh0)
"You can't do it right". What do you base that on? Just the example from Java?
Hi rapidcoder, I believe the situation is not as dark as you describe. The domain of computer technology is young and so is the experience with programming languages. Over the past decade we have seen two unsuccessful approaches to the problem of "exception specifications": one was static exception checking implemented in Java, the other was dynamic exception checking in C++ (C++03). It is good that the two languages took two different approach because we can now see the consequences of both. It appears that the new attempt (with noexcept) tries to learn from the past failures:
1. It is not statically checking for exceptions. On the contrary, it is closer to dynamic specifications. In this sense the the ISO Committee shares your view: do not statically check exceptions.
2. It is not really checking exceptions as the previous approaches did. It only asks one question: is it possible that this function will throw anything or not? In my view, it is simpler than listing all possible exceptions that your function might throw.

I do not know what it is that you find "more complex" in noexcept solution. Is the keyword itself that is difficult to spell? If you are aware of exception safety guarantees as described here:
http://www.boost.org/community/exception_safety.html
http://www2.research.att.com/~bs/except.pdf
http://www2.research.att.com/~bs/3rd_safe.pdf
you will immediately appreciate the noexcept functionality. If you are not, you will not need to use it and the functionality will definitely not harm you.

Regards,
&rzej

The complexity is not about using the noexcept keyword. The complexity is about understanding what it really does, and why it is needed. And as far as I know from reading the discussion list, it is needed mostly for optimisation purposes (avoiding copying and using the new moving constructor feature) - you tell the compiler / library something won't throw, and it tries to use this assumption to make the code faster, without violating exception-safety. Anyway, this feature is probably a new source of incompatibilities between the compilers. For example, will this compile?

1
2
3
noexcept void buggyFunction() {
  throw Exception();
}


If it compiles (as it does now on GCC), how is that better than old empty throws() declaration?


"You can't do it right". What do you base that on? Just the example from Java?


No, from every other language than C++ and Java. Every other language with exceptions took a way of unchecked exceptions. And there is really no problem with that. Unchecked exceptions are perfectly ok, as long as you use them for the purpose exceptions has been created for - for exceptional, rare cases.
Last edited on
If it compiles (as it does now on GCC), how is that better than old empty throws() declaration?


The new, arguably improved, way of exception specifications also made the good old "throw()" work better: compiler can apply move-vs-swap optimizations also on throw(). The important difference is that noexcept allow to conditionally mark your function as non-throwing. Old C++ (C++03) had a problem that you couldn't correctly specify exception specifications for template functions because you didn't know if (and what) the type T was throwing. Consider this function template:

1
2
3
4
template< typename T >
T abs( T const& x, T const& y ) {
    return (x*x) + (y*y);
}


Does it throw or not? It depends if T operations (addition, multiplication, copy construction) throw. With noexcept you can say:

1
2
3
4
5
6
template< typename T >
T abs( T const& x, T const& y ) 
noexcept( noexcept(T((x*x) + (y*y))) )
{
    return (x*x) + (y*y);
}


You may argue that this syntax is silly, but it has one good point about it: it works. This was never possible in C++ before.

No, from every other language than C++ and Java. Every other language with exceptions took a way of unchecked exceptions. And there is really no problem with that. Unchecked exceptions are perfectly ok, as long as you use them for the purpose exceptions has been created for - for exceptional, rare cases.


You are probably right that there may not exist anything better than unchecked exceptions, however a couple of things needs to be noted.

1. The fact that no-one yet knows how to implement compile-time checked static exceptions that work doesn't mean that it is impossible, and I guess it is worth trying. This is how programming languages evolve and get better.
2. I think anyone would agree that compile-time-checked exceptions are useful if we found a way to eliminate problems they cause. So again, it is worth the effort to look for the solution.

C++ is known for experimenting. This experimenting sometimes revolutionizes computer programming (this is the case of STL, or intorducing throw-try-catch syntax for exception handling into the mainstream) and sometimes ends in failure (like exported templates, dynamic exception specifications) but in the end it look like the best approach to make progress in the long run.

Regards,
&rzej
Thanks for explanation. The conditional noexcept is a nice thing, albeit I don't like the additional syntactical complexity it requires.
Last edited on
Topic archived. No new replies allowed.