为什么gcc使用-O0进行一些优化

Hra*_*ant 3 c linux optimization gcc

我使用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);
}
Run Code Online (Sandbox Code Playgroud)

它产生了以下输出:

Inside doJump(): nvar=777 rvar=888 vvar=999
After longjmp(): nvar=777 rvar=222 vvar=999
Run Code Online (Sandbox Code Playgroud)

我的期望是rvar在第二行将是888,因为所有优化都被禁用.

当我从'rvar'的定义中删除'register'或者在'register'前面添加'volatile'时,它输出888.

因此,尽管-O0标志,​​gcc似乎仍然会执行一些优化.

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

Jon*_*ler 6

C11标准适用于longjmp():

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

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

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