Due to integer promotion rules in C++ integer types narrower than int
in usual arithmetic operations are promoted to int
before the operation is applied (simplified explanation).
You can observe this at https://cppinsights.io/ (neat tool right?):
#include <cstdint>
int main()
{
uint8_t a = 'a', b = 'b';
[[mayebe_unsued]] auto r = a * b; // <-- pay attention here
}
is converted internally by the compiler to:
#include <cstdint>
int main()
{
uint8_t a = static_cast<unsigned char>('a');
uint8_t b = static_cast<unsigned char>('b');
int r = static_cast<int>(a) * static_cast<int>(b); // <-- pay attention here
}
As to why, well, it was considered wayback that operations with operands in the platform native type (int
) are faster than with operands with narrower types. I honestly don't know how much truth is to this in modern architectures.