GCC优化了一个无法优化的if子句

时间:2017-02-21 13:23:59

标签: c gcc compiler-optimization

我创建了一个显示我遇到的错误的小代码

#include<stdlib.h>
#include<stdio.h>
int test(char * flag)
{
    char flagger = *flag;
    printf("test value %d", (int) flagger);
    if (flagger != 0x82)
    {
        exit(3);
    }
    else 
    {
        return 0;
    }
}


int main(void)
{
    char flag = 0x82, flag1 = 0x12, flag2 = 0x45;
    //char buf[256];
    test(&flag);
    test(&flag1);
    test(&flag2);
}

编译代码时: gcc -o tester test.c 要么 gcc -o tester test.c -O0

The resulting disassembly code for the function test in gdb is:  
Dump of assembler code for function test:
0x0804849b <+0>:    push   ebp
0x0804849c <+1>:    mov    ebp,esp
0x0804849e <+3>:    sub    esp,0x18
0x080484a1 <+6>:    mov    eax,DWORD PTR [ebp+0x8]
0x080484a4 <+9>:    movzx  eax,BYTE PTR [eax]
0x080484a7 <+12>:   mov    BYTE PTR [ebp-0x9],al
0x080484aa <+15>:   movsx  eax,BYTE PTR [ebp-0x9]
0x080484ae <+19>:   sub    esp,0x8
0x080484b1 <+22>:   push   eax
0x080484b2 <+23>:   push   0x80485c0
0x080484b7 <+28>:   call   0x8048350 <printf@plt>
0x080484bc <+33>:   add    esp,0x10
0x080484bf <+36>:   sub    esp,0xc
0x080484c2 <+39>:   push   0x3
0x080484c4 <+41>:   call   0x8048370 <exit@plt>
End of assembler dump.

如您所见,if优化为始终调用exit的版本。

我尝试了很多东西(还原条件,使用挥发物等),但我没有想到为什么会发生这种情况。 请帮忙吗?

1 个答案:

答案 0 :(得分:12)

在您的系统上,char的范围是-128+127。但0x82为十进制130。从130 > 127开始,此测试永远不会成功。

修复您可以使用的代码:

if ( flagger != '\x82' )

if ( (unsigned char)flagger != 0x82 )

请注意,较早的代码char flag = 0x82是一个超出范围的赋值,它是实现定义的行为。您可以考虑对所有这些变量使用unsigned charuint8_t