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 Precedence: bulk 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