[comp.lang.c] what is this supposed to do?

langer@gibbs.uchicago.edu (Steve Langer) (04/23/91)

Hi -- 
What is the expected output from the following program? Is it defined?

#include <stdio.h>

main() {
   printf("1 << 32 = %o\n", ((unsigned) 1) << 32);
}

Running on a Sun 4 gives 1.
Running on a Sun 3 gives 0.
Running on an Iris gives 1.

K&R (first edition) page 45 says that left shifts fill vacated bits by
0, which does not seem to be happening.

If the shift is done one step at a time the answer is 0 on the Sun 4 and
the Iris, as expected.

#include <stdio.h>

main() {
   int i;
   unsigned x = 1;
   for(i=0; i<32; i++) x <<= 1;
   printf("%o\n", x);
}

E-mail responses are welcome!
    Thanks in advance,
                   Steve
                   langer@control.uchicago.edu

henry@zoo.toronto.edu (Henry Spencer) (04/23/91)

In article <1991Apr22.225641.1122@midway.uchicago.edu> langer@control.uchicago.edu (Steve Langer) writes:
>What is the expected output from the following program? Is it defined?
>   printf("1 << 32 = %o\n", ((unsigned) 1) << 32);

Assuming you're on a 32-bit machine, no, it is undefined.  Translation,
expect different machines to do different things, some of them unpleasant.
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

steve@taumet.com (Stephen Clamage) (04/24/91)

langer@gibbs.uchicago.edu (Steve Langer) writes:

>What is the expected output from the following program? Is it defined?

>#include <stdio.h>
>main() {
>   printf("1 << 32 = %o\n", ((unsigned) 1) << 32);
>}

It is not defined, so the variation in outputs you got is legal.
In 3.3.7, the Standard says "If the value of the right operand
[of the shift operator] ... is greater than or equal to the width in
bits of the promoted left operand, the behavior is undefined."
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

enag@ifi.uio.no (Erik Naggum) (04/24/91)

In article <1991Apr23.003314.5194@zoo.toronto.edu>, Henry Spencer writes:
   In article <1991Apr22.225641.1122@midway.uchicago.edu>, Steve Langer writes:
   >What is the expected output from the following program? Is it defined?
   >   printf("1 << 32 = %o\n", ((unsigned) 1) << 32);

   Assuming you're on a 32-bit machine, no, it is undefined.  Translation,
   expect different machines to do different things, some of them unpleasant.

In concrete terms:

(1) Some machines treat the shift as "modulo word-length", i.e. 1 <<
    32 => 1 << 0 => 1.
(2) Some machines treat the shift as an unsigned integer, and the
    result as "modulo 2**wordlength", i.e. 1 << 32 => 4294967296 => 0.
(3) Some machines do something else when the shift operand is larger
    than the applicable word-size, such as laugh at you.

--
[Erik Naggum]					     <enag@ifi.uio.no>
Naggum Software, Oslo, Norway			   <erik@naggum.uu.no>

jfc@athena.mit.edu (John F Carr) (04/25/91)

In article <ENAG.91Apr24181029@maud.ifi.uio.no>
	enag@ifi.uio.no (Erik Naggum) writes:
>(3) Some machines do something else when the shift operand is larger
>    than the applicable word-size, such as laugh at you.

Which machines and compilers make (1 << wordsize) neither 1 nor 0?

--
    John Carr (jfc@athena.mit.edu)

enag@ifi.uio.no (Erik Naggum) (04/27/91)

In article <ENAG.91Apr24181029@maud.ifi.uio.no>, Erik Naggum writes:
   (3) Some machines do something else when the shift operand is
       larger than the applicable word-size, such as laugh at you.

In article <1991Apr25.153729.2360@athena.mit.edu>, John F Carr writes:
   Which machines and compilers make (1 << wordsize) neither 1 nor 0?

Alternative three was added for the sake of completeness.  I don't
know of any, but it's conceivable that this is an overflow condition.

--
[Erik Naggum]					     <enag@ifi.uio.no>
Naggum Software, Oslo, Norway			   <erik@naggum.uu.no>