Why does, for example, the result of operation between an unsigned short and int always yields an int?
unsigned short s = 65535;
int i = 65535
Expression typeid(s * i * i).name(), gives a value which is out of the range of an int but still the implicit conversion returns an int, why?
There are a set of conversions called the usual arithmetic conversions that are used prior to the evaluation of most arithmetic operators.
Basically, you can consider there to be a few rules for arithmetic on integers:
First, integer arithmetic is never performed with operands “smaller than”
int, so in the case ofshort * signed char, both theshortand thesigned charoperands are promoted toint, the twointvalues are multiplied, and then the result is anint.Second, if one or both of the types are “larger than”
int, the compiler selects a type that is at least “as large” as the type of the largest operand. So, if you havelong * int, theintis promoted to alongand the result is along.Third, if either operand is
unsigned, then the result is unsigned. So, if you havelong * unsigned int, thelongand theunsigned intare both promoted to anunsigned longand the result is anunsigned long.If either operand has floating point type, then floating point arithmetic is performed:
float,double, orlong doubleis used (which one depends on the types of the operands; the full table used to determine the result type can be found on the page linked at the beginning of this answer).Note that the result type is not dependent upon the values of the operands. The type has to be selected by the compiler at compile time, before the values are known.
If the result of
s * i * iis out of range of the result type (int, in your scenario), then you’re out of luck: your program can’t decide at runtime, “oh, I should switch to use along!” because the result type had to be selected at compile time.