C++例外情况,GCC 和“内联函数”旗帜
我正在阅读有关 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些程序并不等同。在 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.