[comp.bugs.sys5] INT_MIN bug

wsinpdb@lso.win.tue.nl (Paul de Bra) (07/18/90)

In sVr3.2 (on the 386) the file <limits.h> contains the definitions
#define INT_MIN 	-2147483648
and
#define LONG_MIN	-2147483648L

which, according to K&R (second edition) are unsigned (constant) expressions
in ANSI C.

This bug (at least a similar one) caused trouble compiling groff with gcc.

Does sVr4.0 have correct values in limits.h?

Paul.
(debra@research.att.com)

karish@mindcrf.UUCP (07/19/90)

In article <1295@tuewsd.win.tue.nl> wsinpdb@lso.win.tue.nl (Paul de Bra) writes:
>In sVr3.2 (on the 386) the file <limits.h> contains the definitions
>#define INT_MIN 	-2147483648
>and
>#define LONG_MIN	-2147483648L
>
>which, according to K&R (second edition) are unsigned (constant) expressions
>in ANSI C.

K&R II, section B11, does not say that the values must be unsigned.

The C Standard specifically requires that they have the appropriate signs:

    2.2.4.2, Numerical Limits

    The values given below shall be replaced by constant expressions
    suitable for use in #if preprocessing directives.  Their
    implementation-defined values shall be equal or greater in
    magnitude (absolute value) to those shown, with the same sign.

    [ ... ]

    INT_MIN                           -32767

    LONG_MIN                     -2147483647
-- 

	Chuck Karish		karish@mindcraft.com
	Mindcraft, Inc.		(415) 323-9000		

wsinpdb@lso.win.tue.nl (Paul de Bra) (07/20/90)

In article <9007181749.AA16031@mindcrf.mindcraft.com> karish@mindcrf.UUCP writes:
>In article <1295@tuewsd.win.tue.nl> wsinpdb@lso.win.tue.nl (Paul de Bra) writes:
>>In sVr3.2 (on the 386) the file <limits.h> contains the definitions
>>#define INT_MIN 	-2147483648
>>and
>>#define LONG_MIN	-2147483648L
>>
>>which, according to K&R (second edition) are unsigned (constant) expressions
>>in ANSI C.
>
>K&R II, section B11, does not say that the values must be unsigned.
>
>The C Standard specifically requires that they have the appropriate signs:
>...

OK, I guess I should have explained the bug more carefully:

-2147483648 is not a numerical constant but a (constant) expression involving
a unary minus sign and a numerical constant 2147483648.
That numerical constant is greater than LONG_MAX so it is an unsigned long.
K&R (second edition, p204) says that 'an integral operand undergoes integral
promotion' (does nothing here since the operand is already unsigned long)
and 'The type of the result is the type of the promoted operand'
which means -2147483648 is an unsigned long.

This means that the values for INT_MIN and LONG_MIN in <limits.h>
on AT&T System V release 3.2 are unsigned long (hence certainly not negative).

The AT&T cc compiler happens to treat INT_MIN and LONG_MIN as negative,
but gcc certainly doesn't and neither should any ansi-c compiler.

Paul.
(debra@research.att.com)

gwyn@smoke.BRL.MIL (Doug Gwyn) (07/24/90)

In article <9007181749.AA16031@mindcrf.mindcraft.com> karish@mindcrf.UUCP writes:
>In article <1295@tuewsd.win.tue.nl> wsinpdb@lso.win.tue.nl (Paul de Bra) writes:
>>#define INT_MIN 	-2147483648
>>#define LONG_MIN	-2147483648L
>>which, according to K&R (second edition) are unsigned (constant) expressions
>>in ANSI C.
>K&R II, section B11, does not say that the values must be unsigned.
>The C Standard specifically requires that they have the appropriate signs:
>    2.2.4.2, Numerical Limits

You missed de Bra's point.  On the 386, the integer constant written
"2147483648" has type (unsigned long int), as specified in 3.1.3.2
Semantics.  The constant expression consisting of "-" followed by
such a numeric string" therefore also has type (unsigned long int).
Since 2.2.4.2.1 specifies that the values of the macros shall be
replaced by expressions that have the same type as would an expression
that is an object of the corresponding type converted according to the
integral promotions, the types should be (int) and (long int),
respectively; thus the implementation is providing incorrect types.