I recently researched that it is better to avoid the use of expressions that mix signed and unsigned types because they can give us back unexpected results ...... examples if int a = -1; unsigned int b = 1; a * b = 4294967295
why if a is a long long type that does not work? because the result is -1 and not the maximum value storable in a long long type as it should be ?
The compiler decides to effectively A: auto c { static_cast<unsignedint>(a) * b };
In principle it could have done B: auto c { a * static_cast<int>(b) };
Or: auto c { static_cast<T>(a) * static_cast<T>(b) };
In other words, there is a set of rules about what to convert. I bet the main rule is that the "larger" type is selected. The long long is big.