[英]Why gcc does some optimizations with -O0
我使用gcc 4.8.4和-O0标志编译了以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
static jmp_buf env;
static void
doJump(int nvar, int rvar, int vvar)
{
printf("Inside doJump(): nvar=%d rvar=%d vvar=%d\n", nvar, rvar, vvar);
longjmp(env, 1);
}
int
main(int argc, char *argv[])
{
int nvar;
register int rvar;
volatile int vvar;
nvar = 111;
rvar = 222;
vvar = 333;
if (setjmp(env) == 0) {
nvar = 777;
rvar = 888;
vvar = 999;
doJump(nvar, rvar, vvar);
} else {
printf("After longjmp(): nvar=%d rvar=%d vvar=%d\n", nvar, rvar, vvar);
}
exit(EXIT_SUCCESS);
}
它产生了以下输出:
Inside doJump(): nvar=777 rvar=888 vvar=999
After longjmp(): nvar=777 rvar=222 vvar=999
我的期望是rvar在第二行将是888,因为所有优化都被禁用。
当我从'rvar'的定义中删除'register'或者在'register'前面添加'volatile'时,它输出888。
因此,尽管-O0标志,gcc似乎仍然会执行一些优化。
有没有办法在gcc中禁用所有优化?
对于longjmp()
,C11标准说:
所有可访问的对象都具有值,并且抽象机器249的所有其他组件在调用
longjmp
函数时具有状态,除了包含调用的函数的本地的自动存储持续时间的对象的值。没有volatile限定类型并且在setjmp
调用和longjmp
调用之间已经更改的相应setjmp
宏是不确定的。249)这包括但不限于浮点状态标志和打开文件的状态。
你正在遇到不确定的价值......标准的符合行为。
如果你发布的代码是在启用了所有警告的情况下编译的,那么就会输出三个警告:
warning: unused parameter 'argc' [-Wunused-parameter]
warning: unused parameter 'argv' [-Wunused-parameter]
以上可以修改替换:
int main( int argc, char *argv[])
同
int main( void )
而重要的一个:
warning: variable 'ravr' might be clobbered by 'longjmp' or 'vfork' [-Wclobbered]
您回答哪个问题,并表明必须在启用所有警告的情况下进行编译。 对于gcc,至少使用:
-Wall -Wextra -pedantic
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.