delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/07/08/19:34:38

From: horst DOT kraemer AT snafu DOT de (Horst Kraemer)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: Infinite loop???
Date: Wed, 08 Jul 1998 23:15:57 GMT
Organization: Unlimited Surprise Systems, Berlin
Lines: 65
Message-ID: <35a3fc6d.35890095@news.snafu.de>
References: <35A3D8C3 DOT 208E6D23 AT cyberdude DOT com>
NNTP-Posting-Host: n31-177.berlin.snafu.de
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

On Wed, 08 Jul 1998 22:38:27 +0200, dns AT cyberdude DOT com wrote:

>I use the following code:
>unsigned short s=1;
>unsigned int   t=1;
>while ((s<<t)!=0) {	// this loop is infinite! but why?
>      t++; }

You just discovered a case of undefined behaviour.

When the expression  s<<t is evaluated, the left operand s is widened
to int, i.e. (int)s<<t will be executed. You cannot avoid this. That's
how the programming language C is defined. The type of the result will
be int therefore.

According to the C standard, a shift operation is undefined if the
right operand is equal or greater than the bit size of the operand.
The bit size of int is 32 and therefore the expression 1<<32 is
undefined although the "mathematical" result is 0.

The reason why 

	1 << 32 == 1

in this implementation is the following: The operation is executed as

	SHL EAX, CL

with EAX=1 and CL=32

The INTEL specification says that any shift operation will be executed
as

	op1 SHIFT (op2 mod 32)

for efficiency reasons. In this case the processor will produce a
SHIFT by 0 and the result is 1.

The operation (unsigned short)(1<<t) will produce 0 whenever t%32 is
in the range 16..31. Therefore (unsigned short)(1<<t) will be 0 if the
increasing t reaches 16 as the cast will cut off bits 16..31 because a
short is 16 bits long.

With BC for DOS you won't have this problem because both short and int
are 16 bit types. In this case 1<<16 is still undefined in theory, but
in this implementation it will work and evaluate to 0, as expected.

Note that

	int i=1;
	i<<32;

will evaluate to 1 in Borland 16 bit C, too, while the literal
expression 1<<32 will evaluate to 0...



"Undefined" means that a C implemention is not obliged to return a
useful or expected result. But it may return a useful result if it
wishes.


Regards
Horst

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019