[comp.lang.c] Interesting Bug in Microsoft C

EGNILGES@pucc.Princeton.EDU (Ed Nilges) (03/05/91)

A colleague wrote a program containing the value -2,147,483,648L (-2**31)
which compiled and ran on Borland Turbo-C but produced a diagnostic "con-
stant to long" on Microsoft QuickC.  When he changed it, replacing
the value with -2,147,483,647L - 1 the program ran on QuickC.

I think what is happening is this.  The compiler is evaluating con-
stants in the lexical analysis phase by (in the case of -2**31) not-
ing the sign, then grabbing each decimal digit, shifting the old
value by multiplying by ten, and adding the next digit to the old
value.  This algorithm has a bug.  It generates the value 2**31 which
is too large for a long integer.

I'm sure that others have bumped into this bug, soooo...


     1.  Is this diagnosis correct?

     2.  If so, when will Microsoft fix this problem?

torek@elf.ee.lbl.gov (Chris Torek) (03/05/91)

In article <12541@pucc.Princeton.EDU> EGNILGES@pucc.Princeton.EDU writes:
>A colleague wrote a program containing the value -2,147,483,648L (-2**31)
>which compiled and ran on Borland Turbo-C but produced a diagnostic "con-
>stant to long" on Microsoft QuickC.  When he changed it, replacing
>the value with -2,147,483,647L - 1 the program ran on QuickC.

If this is a warning, not an error, the compiler is merely being helpful.

The type and value of

	-2147483648L

on a machine with 32-bit `long's is

	<unsigned long, 2147483648UL>

See X3.159-1989 for details.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov

volpe@camelback.crd.ge.com (Christopher R Volpe) (03/05/91)

In article <12541@pucc.Princeton.EDU>, EGNILGES@pucc.Princeton.EDU (Ed
Nilges) writes:
|>A colleague wrote a program containing the value -2,147,483,648L (-2**31)
|>which compiled and ran on Borland Turbo-C but produced a diagnostic "con-
|>stant to long" on Microsoft QuickC.  When he changed it, replacing
|>the value with -2,147,483,647L - 1 the program ran on QuickC.
|>
|>I think what is happening is this.  The compiler is evaluating con-
|>stants in the lexical analysis phase by (in the case of -2**31) not-
|>ing the sign, then grabbing each decimal digit, shifting the old
|>value by multiplying by ten, and adding the next digit to the old
|>value.  This algorithm has a bug.  It generates the value 2**31 which
|>is too large for a long integer.

The compiler is correct. Using the constant "-2147483648L" is a bug
if "2147483648" is too big to fit in a long. C doesn't have negative
constants. It has positive constants preceded by the unary minus operator.
Thus, "-2147483648L" is not a constant, but an integral constant expression
containing a subexpression out of range. The correct way to code for this
value is, as you already noted, "-2147483647L-1".                  
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

volpe@camelback.crd.ge.com (Christopher R Volpe) (03/06/91)

In article <10594@dog.ee.lbl.gov>, torek@elf.ee.lbl.gov (Chris Torek) writes:
|>If this is a warning, not an error, the compiler is merely being helpful.
|>
|>The type and value of
|>
|>	-2147483648L
|>
|>on a machine with 32-bit `long's is
|>
|>	<unsigned long, 2147483648UL>

Yep, right, sorry for wasting bandwidth.                    
==================
Chris Volpe
G.E. Corporate R&D
volpecr@crd.ge.com

browns@iccgcc.decnet.ab.com (Stan Brown) (03/06/91)

In article <17307@crdgw1.crd.ge.com>, volpe@camelback.crd.ge.com (Christopher R Volpe) writes:
> The compiler is correct. Using the constant "-2147483648L" is a bug
> if "2147483648" is too big to fit in a long. C doesn't have negative
> constants. It has positive constants preceded by the unary minus operator.
> Thus, "-2147483648L" is not a constant, but an integral constant expression
> containing a subexpression out of range. The correct way to code for this
> value is, as you already noted, "-2147483647L-1".                  

Would LONG_MIN (defined in <limits.h>) not be superior to these magic
numbers?  I know LONG_MIN is not necessarily -214783648, but it has
the virtue that it will compile.

My opinions are mine:  I don't speak for any other person or company.
                   email (until 91/4/30): browns@iccgcc.decnet.ab.com
Stan Brown, Oak Road Systems, Cleveland, Ohio, USA    +1 216 371 0043