Уровни оптимизации в gcc, изменяющие поведение программы c

Я наблюдаю поведение, которого я не ожидаю, при компиляции этого кода с разными уровнями оптимизации в gcc.

Функциональный тест должен заполнить 64-битное целое число без знака единицами, сдвинуть их биты shift_size влево и вернуть 32 младших бита как 32-битовое целое число без знака.

Когда я компилирую с -O0, я получаю ожидаемые результаты.

Когда я компилирую с -O2, я этого не делаю, если пытаюсь сдвинуть на 32 бита или более.

На самом деле, я получаю именно те результаты, которые ожидал бы, если бы я сдвигал 32-битное целое число на сдвиги, большие или равные ширине битов на x86, то есть сдвиг, использующий только 5 младших битов размера сдвига.

Но я сдвигаю 64-битное число, поэтому сдвиги

Я полагаю, что это ошибка в моем понимании, а не в компиляторе, но я не смог ее понять .

Моя машина: gcc (Ubuntu / Linaro 4.4.4-14ubuntu5) 4.4.5 i686-linux-gnu

#include 
#include 
#include 

uint32_t test(unsigned int shift_size) {
    uint64_t res = 0;
    res = ~res;
    res = res << shift_size; //Shift size < uint64_t width so this should work
    return res; //Implicit cast to uint32_t
}

int main(int argc, char *argv[])
{
    int dst;
    sscanf(argv[1], "%d", &dst); //Get arg from outside so optimizer doesn't eat everything
    printf("%" PRIu32 "l\n", test(dst));
    return 0;
}

Использование:

$ gcc -Wall -O0 test.c 
$ ./a.out 32
0l
$ gcc -Wall -O2 test.c 
$ ./a.out 32
4294967295l

gcc -S -Wall -O0 test.c

gcc -S -Wall -O2 test.c

20
задан user1142769 11 January 2012 в 10:25
поделиться