When evaluating the expression a*b
, the usual arithmetic conversions are applied to both operands. This means that
on platforms on which size_t
has equal or higher rank than int
(which is the case on most platforms), a
is converted to size_t
. Since size_t
is unsigned, the value of a
(which is -6
) will be converted to an unsigned value. On platforms on which size_t
is 64-bit, this value will be 18446744073709551610
. Multiplying this value of a
with the value of b
(which is 100
) will yield the mathematical result 1844674407370955161000
, which is not representable in a 64-bit size_t
. Therefore, assuming a 64-bit size_t
, the actual result will be the mathematical result modulo 18446744073709551616
(2 to the power 64), which is 18446744073709551016
. On platforms on which size_t
is 32-bit, the corresponding result is 4294966696
. Note that this "overflow" will not invoke undefined behavior, because only signed integer overflow will invoke undefined behavior. Unsigned integer overflow is well-defined.
on platforms on which size_t
has a rank less than int
(which are theoretically possible and permitted by the ISO C standard, but unlikely to exist in practice), a
will not be converted to size_t
, so the result will be simply -600
.
For the reasons stated above, depending on which platform you are using, the result of a*b
will likely be either 18446744073709551016
, 4294966696
or -600
.
The line
double dresult = a*b ;
will therefore likely write either the value 18446744073709551016.0
, 4294966696.0
or -600.0
to dresult
, depending on which platform you are using. On your platform, the number 18446744073709551016.0
does not seem to be exactly representable in a double
due to floating-point inaccuracy, so that it gets rounded to 18446744073709551616.0
.
With the line
int result = a*b ;
the situation is not quite as simple. On platforms on which a*b
evaluates to -600
, it is clear that the value -600
will be written to result
. However, on platforms on which a*b
evaluates to 18446744073709551016
, the problem is that this value is not representable in an int
, assuming that an int
is 32-bit. In that case, according to §6.3.1.3 ¶3 of the ISO C11 standard, the value written to result
is implementation-defined or an implementation-defined signal is raised. However, on most platforms, the result is simply the value that is obtained by repeatedly subtracting the maximum number representable in the unsigned version of the target type, plus one, until the result is in the range representable by the type. Therefore, the result would be 18446744073709551016 - 18446744073709551616
, which is -600
. This appears to also be how your platform is behaving.