Section 6.2.1.5 - Usual Arithmetic Conversions of the ANSI C standard states:
"Many binary operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions:
First, if either operand has type long double, the other operand is converted to long double.
Otherwise, if either operand has type double, the other operand is converted to double.
Otherwise, if either operand has type float, the other operand is converted to float.
Otherwise, the integral promotions are performed on both operands. Then the following rules are applied:
If either operand has type unsigned long int, the other operand is converted to unsigned long int.
Otherwise, if one operand has type long int and the other has type unsigned int if a long int can represent all values of an unsigned int the operand of unsigned int is converted to long int; if a long int cannot represent all the values of an unsigned int both operands are converted to unsigned long int.
Otherwise, if either operand has type long int, the other operand is converted to long int.
Otherwise, if either operand has type unsigned int, the other operand is converted to unsigned int.
Otherwise, both operands have type int.
The values of floating operands and of the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby."
So, if both operands have type int, then the result also has type int. If either operand is a long int, then the other operand is converted to a long int and the result is a long int. Our compiler is ANSI C compliant so the following examples produces a long result if a and b are ints:
prodl = (long)a * b;
prodl = a *(long)b;
prodl = (long)a * (long)b;
The following line does not yield the expected 32-bit result either. First a and b are multiplied, but according to the ANSI C Standard, the result is an int. The int is then cast to a long and assigned to prodl:
prodl = (long)(a * b);
Note that on some compilers an int is stored using 32 bits, while on other compilers, an int is stored using 16 bits. The Keil compilers store int types using 16 bits. This explains why some compilers do produce a 32-bit value (they support 32-bit int types).