2017-02-21 46 views
3

я создал небольшой код, показывающий ошибку я столкнулсяНКУ Оптимизирует прочь Условный положение, которое не может быть оптимизирован

#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 тестер test.c или GCC - о тестер 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 <[email protected]> 
0x080484bc <+33>: add esp,0x10 
0x080484bf <+36>: sub esp,0xc 
0x080484c2 <+39>: push 0x3 
0x080484c4 <+41>: call 0x8048370 <[email protected]> 
End of assembler dump. 

Как вы можете видеть, если получает оптимизирован до версии, в которой выход всегда называется.

Я пробовал много вещей (возвращая условное, используя летучие и т. Д.), Но у меня заканчиваются идеи, почему это происходит. Помогите, пожалуйста?

+10

Вот почему вы должны включить свои предупреждения. Я получил предупреждение: сравнение всегда верно из-за ограниченного диапазона типов данных [-Wtype-limits] 'на вашем коде. – HolyBlackCat

+0

На проекте, а не на этом небольшом poc, я использовал -Wall, казалось, мне пришлось использовать -Wextra для этого, чтобы показать. –

+2

Вот почему вы никогда не должны использовать тип 'char' для хранения чего-либо, кроме символов. Используйте 'uint8_t', если вам нужно сохранить значения. – Lundin

ответ

12

В вашей системе диапазон char составляет -128 по +127. Но 0x82 - 130 в десятичной форме. Начиная с 130 > 127, этот тест никогда не будет успешным.

Чтобы исправить код, который вы могли бы использовать:

if (flagger != '\x82') 

или

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

Обратите внимание, что ранее код char flag = 0x82 является вне диапазона назначение, которое определяется реализацией поведение. Вы можете использовать unsigned char или uint8_t для всех этих переменных.