[comp.std.c] shift left arithmetic

aeb@cwi.nl (Andries Brouwer) (09/10/90)

While debugging an Australian computer algebra package
I stumbled over the following: 1<<32 produced 0, but
int a; a=1; a<<32 produced 1. (Of course the word length
of my machine is 32 bits.)
Now I can understand how these values come about, and
each is perfectly acceptable, but shouldnt static evaluation
of expressions produce the same answers as dynamic evaluation?
Is my compiler broken?

[In the application the programmer wrote code depending on
#if 1<<BITS_PER_WORD
; this adds the question whether also the preprocessor should
be consistent in these matters.]

---
main(){
	int a = 1;
	unsigned int b = 1;

	printf("According to the preprocessor, 1<<32 is %s\n",
#if 1<<32
		"nonzero"
#else
		"zero"
#endif
	);

	printf("at compile time it is %d; at run time we get %d %d\n",
		1<<32, a<<32, b<<32);
}
---
According to the preprocessor, 1<<32 is zero
at compile time it is 0; at run time we get 1 1

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/10/90)

In article <2098@charon.cwi.nl> aeb@cwi.nl (Andries Brouwer) writes:
>I stumbled over the following: 1<<32 produced 0, but
>int a; a=1; a<<32 produced 1. (Of course the word length
>of my machine is 32 bits.)
>Now I can understand how these values come about, and
>each is perfectly acceptable, but shouldnt static evaluation
>of expressions produce the same answers as dynamic evaluation?

NO.  When your exceed the bounds of what is guaranteed for the language,
well, there are simply no guarantees.  This example produces explicitly
undefined behavior, and the implementation is free to take whatever
apparently random actions it pleases.

Implementors note:  y=0;...;x<<y; is required to work by the C standard;
on some systems this will require a special-case test in the generated
code, since the hardware shift operation on those systems is incapable
of correctly shifting by 0 bit positions.  (I have seen such machines.)

aeb@cwi.nl (Andries Brouwer) (09/11/90)

vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) writes:

#>While debugging an Australian computer algebra package
#>I stumbled over the following: 1<<32 produced 0, but
#>int a; a=1; a<<32 produced 1. (Of course the word length

#Compiler (may not be) broken -- try 1L<<32. (You didn't
#say that the size of _int_'s was 32 bits).

True, but in fact it was, and 1<<32 and 1L<<32 produce the same results.

ark@alice.UUCP (Andrew Koenig) (09/11/90)

In article <2098@charon.cwi.nl>, aeb@cwi.nl (Andries Brouwer) writes:

> While debugging an Australian computer algebra package
> I stumbled over the following: 1<<32 produced 0, but
> int a; a=1; a<<32 produced 1. (Of course the word length
> of my machine is 32 bits.)

On a machine with 32-bit words, a program that shifts a
vlaue by 32 bits is illegal and the implementation is allowed
to do whatever it likes.
-- 
				--Andrew Koenig
				  ark@europa.att.com