$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Anthony Williams (anthwil_at_[hidden])
Date: 2002-08-28 03:37:07
> What is the type of the sub expression "a*b"? If it is an "int" it needs
> to hold a specific number of bits, which is not to exceed the number of
> bits held by "long".
Given:
int a,b,c;
a*b on its own is of type int, and may overflow, which is undefined behaviour.
a*b/c is still of type int. If a*b overflows this is still undefined behaviour
by the standard, so a compiler may therefore use 2*sizeof(int) precision for
the interim value, in order to get a correct result e.g. (on x86)
mov eax,val1
mov ebx,val2
mov ecx,val3
imul eax,ebx
idiv ecx
which works in all non-overflowing cases, produces the correct result
where a*b/c fits in an int, and produces a divide-by-zero error (!) when the
result overflows. This is as opposed to
mov eax,val1
mov ebx,val2
mov ecx,val3
imul eax,ebx
cdq
idiv ecx
which just produces essentially random results where a*b overflows, but never
overflows. However, it is one more instruction, so there is a performance
penalty.
> What I am opposing is the 2^32 (or whatever the cardinality of "int" is
> on the particular platform) out-of-band values.
Fair enough. My point is that at least on x86, the optimal instruction
sequence has the property that a*b/c is well-defined if it fits in an int,
even when a*b overflows, and that this is acceptable by the C++ Standard, as
one possible instance of the undefined behaviour that ensues when a*b
overflows.
> Well, I thought C++ was a strongly typed language in the extended sense
> of each (sub)expression confining to one type... If the "a*b/c" is
> allowed to transcend those types in between the sub expression and the
> full expression, then I know better.
In the case of undefined behaviour, all bets are off, and the C++ compiler can
do what it likes. However, if it can do something useful, then it makes sense
to do so.
Anthony