throw(), pure and const flags on functions

Mark Mitchell mark@codesourcery.com
Thu Apr 16 03:39:00 GMT 2009


Gabriel Dos Reis wrote:

> Well, the reason I'm pointing this out is that there are
> influencial people in the C++ community who make claims
> tthat 'throw()' is to be discouraged because it makes compilers
> generate worse code.  You are claiming to the opposite, that is
> why the issue is so important.

That's because it depends on where you use throw().

If you write:

  extern void f();
  void g() throw() {
    f();
  }

the "throw()" on "g" probably makes "g" bigger (and/or slower, depending
on how your compiler implements exceptions).  That's because the
compiler has to turn "g" into something like:

  void g() {
    try {
      f();
    } catch (...) {
      std::unexpected();
    }
  }

That try/catch clause costs you.  But, if you do:

  struct S { ~S(); };
  extern void f() throw();
  void g() {
    S s;
    f();
  }

then the "throw()" on "f" makes "g" smaller and/or faster -- because the
compiler no longer needs to generate code to cleanup if "f" throws.  In
other words, the function body is:

    f();
    S::~S();

instead of:

  try {
    f();
  } catch (...) {
    S::~S();
    throw;
  }
  S::~S();

So, an empty exception specification helps callers of that function, but
can hurt the function itself.

Of course, if all the functions called by a function are themselves
"throw()", or if all exceptions are otherwise internally handled via
"catch" clauses that do not rethrow, then an empty throw-specification
has no penalty for the caller, either.  For example:

  extern void f() throw();
  void g() throw () {
    f();
  }

Here, the "throw()" specification on "g" has no penalty, because the
compiler knows that "f" cannot throw exceptions either.  So, in this
case, putting the specification on "g" is unambiguously a good thing.
(Of course, the compiler can deduce that "g" does not throw exceptions
in this case, but as Jan says, separate compilation means that in
general you have "extern void g()" in some header file, and this example
shows that you want to make that "extern void g() throw()" in this case.)

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713



More information about the Libstdc++ mailing list