If unsigned int is just 16 bits wide, then `65535 >> 30` shifts by more positions than the width of the type, which should be undefined behavior, right?
#define NB CHAR_BIT
#define MC ((1 << NB) - 1)
If we have a DSP machine (as mentioned in the article) where CHAR_BIT is 16 and int is 16 bits, then `1 << NB` is `1 << 16` which shifts as much as the width of the type, which I believe is undefined behavior as well.
Regardless of whether you think C's flexible integer sizes are good or bad, and whether it helped propagate the language, there's no denying that if you want to write portable code across machines, you have to put in more effort compared to a language with fixed-size integers. Whether this matters or not is a matter of situation and opinion.
Other than that, I made a simulator where you can set the bit width of each integer type, and then it shows you how `x operation y` gets promoted to some output integer type. <a href="https://www.nayuki.io/page/summary-of-c-cpp-integer-rules" rel="nofollow">https://www.nayuki.io/page/summary-of-c-cpp-integer-rules section "Conversion rules simulator"
The rules for compile time evaluation are the same as runtime, so it's UB in both cases. The UB may resolve differently but isn't required to.
Preprocessor constant expressions are evaluated with at least the range of the largest integer type available at run time. The C standard requires that "long" have at least 32 bits. So a shift right by 30 in a preprocessor constant expression looks good to me.
Aren't you talking about how expressions are evaluated in #if there? An expression form that shows up in a macro that is then embedded in normal C code just becomes part of the C code that could potentially get evaluated with C rules at compile time; it's not inherently evaluated at preprocessor time.
I am, yes! Thanks for the correction! I thought it was an #if expression, but it presumably isn't. (You can expand arbitrary macros in an #if expression, but it's not often done.)
nayuki · · focus · HN ↗
Regardless of whether you think C's flexible integer sizes are good or bad, and whether it helped propagate the language, there's no denying that if you want to write portable code across machines, you have to put in more effort compared to a language with fixed-size integers. Whether this matters or not is a matter of situation and opinion.
Other than that, I made a simulator where you can set the bit width of each integer type, and then it shows you how `x operation y` gets promoted to some output integer type. <a href="https://www.nayuki.io/page/summary-of-c-cpp-integer-rules" rel="nofollow">https://www.nayuki.io/page/summary-of-c-cpp-integer-rules section "Conversion rules simulator"
Neywiny · · focus · HN ↗
someonebaggy · · focus · HN ↗
Neywiny · · focus · HN ↗
someonebaggy · · focus · HN ↗
bloak · · focus · HN ↗
dasyatidprime · · focus · HN ↗
bloak · · focus · HN ↗