C++例外情况,GCC 和“内联函数”旗帜

发布于 2024-10-07 01:49:41 字数 1956 浏览 0 评论 0原文

我正在阅读有关 C++ 异常处理的文章。我在 StackOverflow 上找到了这个主题。有一些简单的测试,我对它们做了一些更改:

C 代码:

#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++ 代码:

#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;
        }

         }
}

我都使用 -O2 优化选项进行编译,结果 C 程序要快得多:

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

输出可执行文件的大小完全相同,但使用 -finline 编译时- 函数程序要快得多。我试图研究汇编器输出,

因为 -finline-functions 仅在 GCC 优化的第三级中启用,所以它在某种程度上很危险,所以请告诉我为什么我不应该在生产代码中使用?

我在 Intel Core 2 Duo(64 位模式)上使用 GCC v4.5.2。

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半世蒼涼 2024-10-14 01:49:41

这些程序并不等同。在 C 版本中,您返回哨兵,但在 C++ 中,您抛出它。异常不一定会返回给调用者,因此在调用站点和被调用函数中都放置了一些额外的机制来安排展开堆栈。 C 中最接近 C++ 异常的是 longjmp

当编译器决定执行内联优化时,调用者和被调用者都是已知的,并且异常可以解析为更便宜的分支。

两者都是“安全”的,但不包含异常的代码比使用异常的代码更小、更快,这是很正常的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文