2015-09-21 3 views
2

Почему этот код печатает два разных номера для f1 и f2:?сдвиг Работа в C++

int main() { 
    int a = 32; 
    int f1 = (0xffffffff << a); 
    int f2 = (0xffffffff << 32); 

    std::cout << f1 << std::endl; // print -1 
    std::cout << f2 << std::endl; // print 0 
} 

Для f2, я получаю это предупреждение, но ничего для f1:

предупреждение: левый отсчет сдвига > = ширина типа

Я использую г ++ 4.4.7

+0

http://stackoverflow.com/questions/18918256/is-right-shift-undefined-behavior-if-the-count-is-larger-than-the-width-of-the-t/18918340#18918340 – ewcz

ответ

2

Короткий ответ будет invoking undefined behavior when shifting by width of type or greater.

Чем дольше ответ, что во втором случае GCC может константу сложить выражение и просто переходит в ноль (see it live on godbolt):

movl $0, -28(%rbp) #, f2 

в то время как в первом случае он фактически выполняет сдвиг:

movl -20(%rbp), %eax # a, tmp63 
movl $-1, %edx #, tmp64 
movl %edx, %ebx # tmp64, 
movl %eax, %ecx #, 
sall %cl, %ebx #, 
movl %ebx, %eax #, D.21248 
movl %eax, -24(%rbp) # D.21248, f1 

Поскольку мы вызываем неопределенное поведение, у нас нет ожиданий результата. Непоследовательные ответы на то, что, по-видимому, должны давать один и тот же ответ, являются совершенно приемлемым неопределенным поведением.

+0

хороший ответ .. godbolt классно! – Kickaha

1

Результат

0xffffffff << 32 

является

18446744069414584320 

, который намного больше, то std::numeric_limits<int>::max()

Если ваша система представляет int как 4 байта, то указанное выше значение является

2147483647 

Signed overflow is undefined behavior, поэтому оба имеют неопределенное поведение.

+1

op спрашивает, почему поведение по-разному для двух версий, даже если 'a' равно 32. –

+0

Я ожидаю получить 0 для обоих. для f2 это правильно, я получаю 0. Но я получаю -1 для f1, который использует вместо 32. – Nargesoo

+1

@Nargesoo Вы не должны * ожидать * ничего, ваш код демонстрирует неопределенное поведение, поэтому результат не указан. Тот факт, что вы считаете вывод '0' правильным, не согласуется с стандартом C++. – CoryKramer

Смежные вопросы