0

I was reading articles about exception handling in C++. I found this topic on StackOverflow. There were to simple tests, I changed them a bit:

C code:

#include <stdio.h>
#include <time.h>

#define BIG 10000000000

long f( long n ) {
    long r = 0, i = 0;
    for ( i = 0; i < 1000; i++ ) {
        r += i;
        if ( n == BIG - 1 ) {
                return -1;
        }
    }
    return r;
}

int main() { 
    long i = 0, z = 0;
    for ( i = 0; i < BIG; i++ ) {
        if ( (z = f(i)) == -1 ) { 
                break;
        }
    }
}

C++ code:

#include <stdio.h>
#include <time.h>

#define BIG 10000000000

long f( long n ) {
    long r = 0, i = 0;
    for ( i = 0; i < 1000; i++ ) {
        r += i;
        if ( n == BIG - 1 ) {
                throw -1;
        }
    }
    return r;
}

int main() { 
    long i = 0, z = 0;
    for ( i = 0; i < BIG; i++ ) {
        try {
         z += f(i); 
        }
        catch(int tmp) {
                break;
        }

         }
}

I compiled both with -O2 optimization option, in result C program was much faster:

gcc -O2 kod.c -o prog_c
time ./prog_c

real 0m8.610s
user 0m8.520s
sys  0m0.010s

g++ -O2 kod.cpp -o prog_cpp
time ./prog_cpp 

real 0m25.460s
user 0m25.260s
sys  0m0.020s

size prog_cpp 
   text    data     bss     dec     hex filename
   2019     592      32    2643     a53 prog_cpp

g++ -O2 kod.cpp -o prog_cpp -finline-functions
time ./prog_cpp 

real 0m8.412s
user 0m8.390s
sys  0m0.000s

size prog_cpp 
   text    data     bss     dec     hex filename
   2019     592      32    2643     a53 prog_cpp

Output executable files are exactly the same size, but when compiled with -finline-functions program is much faster. I tried to investigate assembler output,

Because -finline-functions is enabled only in third level of GCC optimization it's dangerous somehow, so please tell me why I shouldn't be used in productive code?

I use GCC v4.5.2 on Intel Core 2 Duo (64 bit mode).

Community
  • 1
  • 1
Goofy
  • 5,187
  • 5
  • 40
  • 56

1 Answers1

1

These programs are not equivalent. In the C version, you return your sentinel, but in the C++, you throw it. An exception does not necessarily return to the caller, and so some additional machinery is placed both at call sites and in the called function to arrange to unroll the stack. The closest thing in C to a C++ exception is a longjmp.

when the compiler decides to perform an inline optimization, then caller and callee are both known, and the exception can be resolved into much cheaper branches.

Both are 'safe', but it's very normal for code not containing exceptions to be a little smaller and a little faster than code that does use exceptions.

SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • Yes, I'm aware, that these program does not equal (I found them). I was only curious about such a huge difference in run time between executables built with and without this optimization flag. I had investigated assembler output one more time and found, which part was inlined. On the other hand, I didn't know, that direct function call are so expensive on x86... – Goofy Dec 10 '10 at 22:35