Note: this has nothing to do with optimization. Optimization doesn’t change semantics of the code.
(1) At most it exposes errors in already invalid code, that might’ve been missed in other circumstances.
I see, so basically I'd have to put "u" on the end of every constant anyway to make sure I don't end up with half my range. presumably at least one constant needs to be "ul" to promote the calculation to 32 bit.
That depends on the intention. A multiplication of two
unsigned int values will be done entirely within
unsigned int. For most of the inputs it will overflow. An unsigned overflow is well defined in both C and C++, but it may not be what you want.
Typically what I do it I don't put constants in expressions.
uint16_t a;
uint16_t b;
uint32_t c = a * b;
Doesn't leave much room for imagination.
So you going around telling everything to be ul, may not be your intended result due to what choice of (slow) multiply it picks.
Except that this code shows exactly what has been explained to be wrong: both in this thread and the document you have yourself linked.
uint32_t in the third line bears no significance for the multiplication. That multiplication is determined by the types of
a and
b, which are
uint16_t in this case. Depending on the platform that may be
signed multiplication and, again depending on the platform, that may overflow.
If you ever used this code and it was giving the results you expected, it’s because of the lucky circumstances. Typicall this is a combination of working with 2’s complement representation of integers and compilers optimizing undefined cases. Since a compiler is allowed to do so, it substitutes that with code acting as if the operation was valid (which is more optimal). By magic of 2’s complement the intermediate result, despite being actually invalid, has binary representation matching what it would be if the whole operation was unsigned. And since the code downstream re-interprets it as unsigned, it happens to be what you expected.
But this is an accident. This is not what this expression indicates in terms of language’s semantics.
____
(1) The exception being bugs in the compiler itself, but those are very rare compared to mistakes of whoever uses the compiler.