为什么gcc使用-O0

时间:2015-08-09 17:27:00

标签: c linux gcc optimization

我使用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,因为所有优化都被禁用。

当我删除&#39;注册&#39;根据&#39; rvar&#39;的定义或者当我添加“易变”的时候在&#39;注册&#39;前面,输出888。

所以看起来gcc仍然会在-O0标志的情况下进行一些优化。

有没有办法在gcc中完全禁用所有优化?

2 个答案:

答案 0 :(得分:6)

C11标准适用于longjmp()

  

所有可访问的对象都具有值,以及抽象机器 249)的所有其他组件   有状态,截至调用longjmp函数时,除了值   自动存储持续时间的对象是包含该函数的函数的本地对象   调用没有volatile限定类型的相应setjmp宏   并且在setjmp调用和longjmp调用之间进行了更改   不确定的。

     

249)这包括但不限于浮点状态标志和打开文件的状态。

你遇到了不确定的价值......标准的符合行为。

答案 1 :(得分:3)

如果您发布的代码是在启用了所有警告的情况下编译的,那么就会输出三个警告:

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