Integral Promotions happen in C++. Nonetheless, testing the expressions practically, isn't a bad idea to understand whats happening under the hood...
#include <typeinfo>
#include <iostream>
#include <boost/type_index.hpp>
using namespace std;
int main(){
#define MYMACRO(n) (((uint16_t)0 - 1) >> (16 - (n)))
std::cout << std::hex << MYMACRO(1);
std::cout << "\n-----\n";
#undef MYMACRO
#define MYMACRO(n) (((uint32_t)0 - 1) >> (32 - (n)))
std::cout << std::hex << MYMACRO(1);
std::cout << "\n--++++--\n";
std::cout << boost::typeindex::type_id<decltype((uint16_t)0)>().pretty_name() << std::endl;
std::cout << boost::typeindex::type_id<decltype((uint16_t)0 - 1)>().pretty_name() << std::endl;
std::cout << boost::typeindex::type_id<decltype((uint32_t)0 - 1)>().pretty_name() << std::endl;
}
The integer type of the expression after the shift operator isn't relevant in our case. From the output of the above program as seen Live On Coliru
ffffffff
-----
1
--++++--
unsigned short
int
unsigned int
Summarizes that:
The sub-expression: (uint16_t)0
yields an unsigned short
as usual on most platforms
The expression: (uint16_t)0 - 1
yields a type of int
; because of integer promotion rules. 1
is an integral constant of type int
The expression: (uint32_t)0 - 1)
yields a type of unsigned int
; still because of usual arithmetic conversions. an unsigned int
is considered larger than an int