From: volpe@bart.NoSubdomain.NoDomain (Christopher R Volpe)
Newsgroups: comp.std.c
Subject: Re: Is INT_MAX<<1 defined?
Date: 14 Dec 92 18:00:46 GMT
Reply-To: volpe@ausable.crd.ge.com
Organization: GE Corporate Research & Development

In article <Bz8MtG.479@jrd.dec.com>, diamond@jit533.jit.dec.com (Norman Diamond) writes:
|> In article <8322@charon.cwi.nl> dik@cwi.nl (Dik T. Winter) writes:
|> >What it comes down to is that << is not a mathematical operation, there
|> >is nothing in mathematics that tells us that 16384 << 1 equals 32768.
|> 
|> Additional non-mathematical operations:
|>   ++ (prefix and postfix)
|>   -- (prefix and postfix)
     
  The definition of their side effect is perfectly mathematical. It computes
sum or difference, and therefore can overflow.

|>   [] (subscript, C definition using pointers)
|>   () (function call, C definition using pointers)
|>   () (cast)
|>   unary  &  *  !
|>   unary  ~  on a value that is not a single bit
|>   binary /  on integral values where the mathematical quotient is not integral
|>   binary .  ->  sizeof  %  &  ^  |  &&  ||  =  *=(etc.)  ,

Moot point, since none of these can generate an arithmetic overflow due to
a result not fitting. The "op=" operators are and exception, and I consider
them to be in the same category as "++" and "--", i.e., their side effects
are perfectly mathematical, and that's what can overflow. 

In a nutshell, mathematical operators can overflow, non-mathematical
operators cannot.

|> >    Where in the standard does it tell
|> >    us that for signed (16 bit) int 16384, 16384 << 1 is 32768?

It doesn't. It tells us that the bits are shifted. So look at the bits
the way your machine does, and that's what the value is.

|> 
|> I think the standard is unclear enough to recommend an interpretation ruling.

Yeah, ok.

|> However, for comparison, for unsigned types, the standard says explicitly
|> that the value of the result is a mathematical multiplication followed by
|> a mathematical modulo reduction -- if it were a representation multiplication,

That statement is completely unnecessary. That simple fact can be derived
from the properties of unsigned integers.

|> the modulo reduction would have been a no-op and would not have been stated.

No one is claiming that it is a representation multiplication. The standard
is simply clarifying the behavior by saying (quite unnecessarily) that
a *representation* *shift* behaves like a *mathematical* *multiplication*
followed by modulo reduction for unsigned types, the way mathematical 
multiplication is always followed by modulo reduction for unsigned types.

|> 
|> >    Is an implementation not allowed to define it as -32768?  Or whatever?
|> 
|> Implementations are allowed to define what happens when signed results don't
|> fit in the corresponding types.  They aren't REQUIRED to, that's all.

True. But it is not clear at this point that it's possible (more
precisely, that it's meaningful to say) that a shift result can not fit
in the corresponding type.

|> 
|> >    But in all there is no definition in *mathematics* for this operation.
|> [...]
|> >The bottom-line is that shifting is not a mathematical concept, [...]
|> 
|> That didn't prevent a ton of other C operations from being defined on
|> mathematical values.  Actually maybe the standards committees can start
|> to get an idea of just how unpopular this stunt is.  However, that is what
|> they did, following the path of other language committees.

Again, there is never a danger of the results of such operations 
causing arithmetic overflow. Since none of the other non-mathematical
operations can cause this, why should bit shifting?

|> --
|> Norman Diamond       diamond@jit081.enet.dec.com
|> If this were the company's opinion, I wouldn't be allowed to post it.
|> "It's been a lovely recession."

-- 
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com