views:

88

answers:

2

It seems to me that if you have some C++ code like this:

int f()
{
  try {
    if( do_it() != success ) {
      throw do_it_failure();
    }
  } catch( const std::exception &e ) {
    show_error( e.what() );
  }
}

The C++ compiler should be able to optimize the throw and catch into almost a simple goto.

However, it seems to me from my experience viewing disassembly and stepping through code that the compilers always jump through the very messy exception handling libraries.

Why do they do that? Is there some language requirement that prevents optimizing? What if it was:

int f()
{
  try { throw std::runtime_error("Boo!"); }
  catch ( const std::exception &e ) { std::cout << e.what() << std::endl; }
}

Why does the compiler not just rewrite that as

int f()
{
  std::cout << "Boo!" << std::endl;
}
+4  A: 

Because do_it() could throw a different exception, before you throw do_it_failure();

As for your second example, a compiler could do it, but it would have to be treated as a special case, so why bother for such a pathological case?

James Curran
The function *could* throw a different exception. But the compiler *knows* that at least one execution path *does* throw and is caught immediately so for that path it could jump directly to the catch block. If it wanted to.
Zan Lynx
+5  A: 

Why do they do that?

Because C++ exception are for, well, exceptional circumstances and performance under exceptional circumstances doesn't really matter.

C++' exceptions were designed with that in mind, making sure compiler vendors could deliver near-optimal performance in the common case of no exceptions being thrown, at the cost of worse-than-possible performance in the odd case when exceptions are thrown.

From the very beginning users were encouraged to use exceptions only under exceptional circumstances, and implementers were encouraged to optimize the no-exception case (destructor addresses must be stored somewhere in order to call destructors when an exception comes by) at the cost of the exceptional case.
And while implementers could certainly spend resources at also optimizing the odd exceptional case, most users wouldn't like that, since there's always so much more important things that need improvment.

sbi