www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/04/22/17:50:57

Xref: news2.mv.net comp.os.msdos.djgpp:2958
From: alexlehm AT rbg DOT informatik DOT th-darmstadt DOT de (Alexander Lehmann)
Newsgroups: comp.os.msdos.djgpp
Subject: Re: LONG_MIN question
Date: 22 Apr 1996 15:47:15 GMT
Organization: Technische Hochschule Darmstadt
Lines: 83
Message-ID: <4lg9m3$1cod@rs18.hrz.th-darmstadt.de>
References: <01I3RZ7ZOPMQ005280 AT cc DOT uab DOT es>
NNTP-Posting-Host: hp62.rbg.informatik.th-darmstadt.de
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

x DOT pons AT cc DOT uab DOT es (ILGES AT cc DOT uab DOT es) wrote:
: Dear programmers,

: If I write a sentence like this: 

:   if (0L < -2147483647L)
                       ^ don't you mean 2147483648L?
:      .....
: the result is TRUE, although it should not be. In fact, DJGPP warns it
: when compiling:
:   "warning: decimal constant is so large that it is unsigned"

: It is possible to do the right comparison by writing
:   if (0L < LONG_MIN)
:      .....

: LONG_MIN is defined in <limits.h> as:
:    #define LONG_MIN (-2147483647L-1L)

: I suppose this makes the code a bit slower. I'd like to know:
:   1-Is there some way to avoid this subtraction each time I compare a value
:     and -2147483648L
:   2-Why this problem exists? Why doing (-2147483647L-1L) does not produce
:     the same problem?
:   3-Why DJGPP defines
:       #define SHRT_MIN (-32768)
:     and BC++4.52 defines
:       #define SHRT_MIN (-32767-1)
:     even for 32 bit applications?

The problem with -2**31 is a rather bizarre feature of the type promotion
rules in ANSI. The language syntax definition doesn't define negative number
literals, rather the negative numbers are generated by the unary - operator.
This I think is to make an expression like: 2-1 easier to parse, other
languages (e.g. Prolog) consider the -1 to be one token and report a syntax
error, so you have to write 2- 1.

So an expression like 0 < -2147483648L is parsed as (0) < (-(2147483648L)).
Now unsigned constants are (I think) int until they are larger than MAX_INT,
then unsigned int, then long, then unsigned long (since in gcc
sizeof(int)==sizeof(long), the int part doesn't really happen, but 16 bit int
compilers do that).
The constant (2147483648L) is too large to fit into a signed long, so it
is considered an unsigned long (even though there is a L).
Now the unary - operation is defined on unsigned numbers as well as on signed
ones, so the constant remains unsigned even after that. Negating the number
doesn't work (neither as signed nor as unsigned) since the 2s complement of
the number is the number again.

The reason why it works when doing (-2147483647L-1L) instead is that then
both constants are signed longs and the result fits into a signed long as
well. Note that this doesn't actually create a subtraction operation in
the resulting assembler code (at least with optimisation turned on)
(You may not even get the if conditional calculated, since it is constant at
compile time, gcc is pretty smart with respect to evaluating constant sub-
expressions).
(I would include a sample asm code piece here, but I am writing this on a
 hppa risc machine and the code is pretty unreadable).

Another possibility to get the constant is to do an explicit cast to long,
this way, the constant is signed ((long)(-2147483648)).


As for the 3rd question, I'm not sure what the ANSI spec says about the type
of the *_MIN/*_MAX constants, I think the smallest type constants are usually
represented in is int, so if int is 16 bits wide, the first definition may
cause the same problem as LONG_MIN, with 32 bit ints it works anyway.
So if they have a definition that works with both modes, they can use that
one and don't have to clobber up their headers with additional #ifdefs.
(I would expect that bc has similar optimizations for evaluating constant
expressions as gcc).
BTW: I have no idea if bcc in 32 bit mode has 32 bit ints (I think the mode
is called 32 bit because of the address space), but I guess it would be a
good idea.


bye, Alexander

--
Alexander Lehmann,                                  |  "On the Internet,
alex AT hal DOT rhein-main DOT de  (plain, MIME, NeXT)         |   nobody knows
alexlehm AT rbg DOT informatik DOT th-darmstadt DOT de (plain)     |   you're a dog."
<URL:http://www.student.informatik.th-darmstadt.de/~alexlehm/>

- Raw text -


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