UB со сдвигами беззнаковых переменных
Код следующий:
#include <iostream>
int main ()
{
unsigned int a = 1;
unsigned int b = 5;
unsigned int c = (a << (a << b)) << b;
std::cout << "s : c \t\t= " << c << std::endl;;
unsigned int x = 32u;
std::cout << "s : 1u<<x \t= " << (1u << x) << std::endl;
return 0;
}
Компилирую в mingw (аналог gcc в винде). Под линуксом также пробовал через gcc - результат такой же. В зависимости от уровня оптимизации разный результат:
-O0:
s : c = 32
s : 1u<<x = 1
-O2:
s : c = 0
s : 1u<<x = 0
В коде по-видимому есть UB, но найти я его не могу, кажется, что там идут сдвиги беззнаковых переменных, а они UB не являются, и по логике оба ответа должны быть нулями.
For unsigned a, the value of a << b is the value of a * 2^b , reduced modulo 2^N where N is the number of bits in the return type (that is, bitwise left shift is performed and the bits that get shifted out of the destination type are discarded).
Что тут не так?