help-gplusplus
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: cost of throw() ?


From: Philippe Amarenco
Subject: Re: cost of throw() ?
Date: Wed, 05 Oct 2005 22:32:21 +0200
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/22.0.50 (gnu/linux)

Philippe Amarenco <philippe@amarenco.net> writes:

> hi all,
>
> is there a real benefit from declaring functions that don't throw
> exceptions as throw() ?
>
> if yes, what is the cost in time and space when
> - calling no functions
> - calling a function declared as thow()
> - calling a function not declared as thow()
> from a function declared as thow() ?


here is what I found:

/*
 * compile with g++ -W -Wall -O3 -c throw.cc
 * this test was done for a x86 architecture.
 *
 * I did not run benchmark, I just looked at the generated
 * assembly code.
 */

/**** function that call no other functions *******/
/* these two have the same asm code
 * the cost of exception handling is 3 bytes (is it really needed for 
 * this function?).
 */
int throw_op_nothrow(int x, int y)
{
  return x + y;
}
/* for some reason (?) the code for propagation (3 bytes) is still generated */
int nothrow_op_nothrow(int x, int y) throw()
{
  return x + y;
}

/* these two execute the same code if nothing is thrown
 * the code for generating the "throw" is quite large (42 bytes)
 * (larger than the original function).
 * these two use 0x10 extra bytes of stack space.
 */
int throw_op_throw(int x, int y)
{
  if (!x)
    throw 42;
  return x + y;
}
/* this one adds code for a try{}catch(...){terminate();} (19 bytes)
 * but does not generate the code for propagation (3 bytes).
 */
int nothrow_op_throw(int x, int y) throw()
{
  if (!x)
    throw 42; /* could be replaced directly by terminate(). */
  return x + y;
}

/***** function that call a function *********/
int foo_throw(int x);
int foo_nothrow(int x) throw();

/* for all the following, the cost of exception propagation is 8 bytes. */

/* these three have the same asm code. */
int fun_throw_op_nothrow(int x, int y)
{
  return x + foo_nothrow(y);
}
/* it keeps the exception propagation code (??) */
int fun_nothrow_op_nothrow(int x, int y) throw()
{
  return x + foo_nothrow(y);
}
int fun_throw_op_throw(int x, int y)
{
  return x + foo_throw(y);
}

/* this one adds code for try{}catch(...){terminate();} (19 bytes).
 * it keeps the exception propagation code (??)
 * and user 0x10 extra bytes of stack space.
 */
int fun_nothrow_op_throw(int x, int y) throw()
{
  return x + foo_throw(y);
}

/**** with a try block ****/
/* these two have the same asm code, also same as func_nothrow_op_nothrow. */
int try_throw_op_nothrow(int x, int y)
{
  try {
    return x + foo_nothrow(y);
  } catch (...) {
    return x;
  }
}
/* again, it keeps the exception propagation code. */
int try_nothrow_op_nothrow(int x, int y) throw()
{
  try {
    return x + foo_nothrow(y);
  } catch (...) {
    return x;
  }
}

/* this one adds code for the catch(...){} (18 bytes)
 * the propagation code is now 6 bytes
 * and use 0x10 extra bytes of stack.
 */
int try_throw_op_throw(int x, int y)
{
  try {
    return x + foo_throw(y);
  } catch (...) {
    return x;
  }
}

/* this one adds even more code to the previous,
 * for the catch(...){terminate();} (19 bytes).
 */
int try_nothrow_op_throw(int x, int y) throw()
{
  try {
    return x + foo_throw(y);
  } catch (...) {
    return x;
  }
}

/*
 * other wierdness: if only two functions are compiled, then
 * the exception propagation code is never generated for the
 * throw() functions.
 */


-- 
Philippe Amarenco, aka Phix
epita 2007 - LSE - EpX


reply via email to

[Prev in Thread] Current Thread [Next in Thread]