Boost logo

Boost :

From: David Bergman (davidb_at_[hidden])
Date: 2002-08-28 07:47:18


Anthony,

I am aware that there are ways to efficiently keep those top 32 bits in
an X86, through an imul op, and similar opcodes in other architectures.

And, obviously, it is probably a good thing to do when "a*b" overflows,
since we indeed are free to do whatever we want as soon as an undefined
operation is executed. The C++ Standard does not impose *any*
restriction on the behavior in that case, or, as you put it, "all bets
are off".

I am just curious as to the type of the subexpression "a*b". Even though
"all bets are off" regarding the actual values at each step, is the
restriction imposed by the (32 bit) type int no longer applicable? In
other words, is "a*b" no longer typed?

Even though an implementation is free to do *whatever* it wants, before
and after an undefined operation, w.r.t The C++ Standard, I really would
like the types to stay intact, in representation and behavior, which in
this case would defy the expression "a*b" denoting a 2*sizeof(int) byte
long value...

Anyhow, we all know that there is nothing to be derived from our
"bible", The International Standard, in these cases, which makes these
discussions not only out-of-bounds w.r.t the Boost library, but also
metaphysical if we believe C++ to be the reality.

/David

-----Original Message-----
From: boost-bounces_at_[hidden]
[mailto:boost-bounces_at_[hidden]] On Behalf Of Anthony Williams
Sent: Wednesday, August 28, 2002 4:37 AM
To: boost_at_[hidden]
Subject: RE: [boost] Re: (boost) Re: A pure C/C++ question

> 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

_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk