Oh, you are right, this can be problematic, although I don't like your solution either, since unsigned long is going to be larger than 32-bit on 50% of the platforms (not really, but you know the drill, Linux: 64-bit, Windows: 32-bit).
Re:Static Integer Types
by rssoconnor on Thursday July 01, 2021 @12:18PM
(#27700768)
Indeed. The trick here appears to be to write (1U*x << 31) so that 1U*x becomes a type that is the larger of uint32_least_t and unsigned int.
Yup. Alternatively ((0U + x) << 31). I first thought about this problem years ago: https://stackoverflow.com/questions/39964651/is-masking-befo...
Implementing cryptographic algorithms using uint32_least_t can be dangerous. Suppose that short is 32 bits wide and int is 48 bits wide. Your uint32_least_t might be mapped to unsigned short. When you do something like (x << 31), x gets promoted to signed int, and then you might be shifting a 1 into the sign bit, which is undefined behavior. So I would say that a better idea is to use unsigned long, which is guaranteed not to promote to a higher-rank type.