Xi Wang 1bfec89b99 rc: avoid undefined C
There are two bugs in pdec() on INT_MIN:

* wrong output.

`n = 1-n' should be `n = -1-n' when n is INT_MIN.

* infinite loop.

gcc optimizes `if(n>=0)' into `if(true)' because `-INT_MIN' (signed integer overflow) is undefined behavior in C, and gcc assumes the negation of a negative number must be positive.  The resulting binary keeps printing '-' forever given INT_MIN.

Try the simplified pdec.c below.

$ gcc pdec.c
$ ./a.out -2147483648
--214748364*

$ gcc pdec.c -O2
$ ./a.out -2147483648
<infinite loop>

$ gcc pdec.c -O2 -D__PATCH__
$ ./a.out -2147483648
-2147483648

=== pdec.c ===

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#define io void

void pchr(io *f, int c)
{
        putchar(c);
}

void pdec(io *f, int n)
{
        if(n<0){
#ifndef __PATCH__
                n=-n;
                if(n>=0){
                        pchr(f, '-');
                        pdec(f, n);
                        return;
                }
                /* n is two's complement minimum integer */
                n = 1-n;
#else
                if(n!=INT_MIN){
                        pchr(f, '-');
                        pdec(f, -n);
                        return;
                }
                /* n is two's complement minimum integer */
                n = -(INT_MIN+1);
#endif
                pchr(f, '-');
                pdec(f, n/10);
                pchr(f, n%10+'1');
                return;
        }
        if(n>9)
                pdec(f, n/10);
        pchr(f, n%10+'0');
}

int main(int argc, char **argv)
{
        int n = atoi(argv[1]);
        pdec(NULL, n);
        putchar('\n');
}

R=rsc
CC=plan9port.codebot
https://codereview.appspot.com/7241055
2013-03-19 14:36:50 -04:00
2012-03-05 16:36:31 -05:00
2012-10-21 12:01:13 -04:00
2005-07-18 22:52:05 +00:00
2005-09-13 01:24:50 +00:00
2012-11-26 00:13:04 -05:00
2005-02-13 22:09:54 +00:00
2009-04-30 07:28:37 -07:00
2007-11-27 15:39:06 -05:00
2013-03-11 17:26:11 -04:00
2004-04-21 23:43:46 +00:00
2005-01-13 04:56:07 +00:00
2005-01-27 19:28:22 +00:00
2013-03-19 14:36:50 -04:00
2007-11-27 15:39:06 -05:00
2008-05-10 13:38:21 -04:00
2005-11-25 13:18:11 +00:00
2013-01-30 17:45:21 -08:00
2013-01-30 17:45:28 -08:00
2009-04-30 08:30:49 -07:00
2005-11-25 13:18:11 +00:00
2005-08-10 16:59:19 +00:00
2005-11-28 16:36:57 +00:00
2005-08-31 04:00:14 +00:00

This is a port of many Plan 9 libraries and programs to Unix.

* Installation

To install, run ./INSTALL.  It builds mk and then uses mk to
run the rest of the installation.  

For more details, see install(1), at install.txt in this directory
and at http://swtch.com/plan9port/man/man1/install.html.

* Documentation

See http://swtch.com/plan9port/man/ for more documentation.
(Documentation is also in this tree, but you need to run
a successful install first.  After that, "9 man 1 intro".)

Intro(1) contains a list of man pages that describe new features
or differences from Plan 9.

* Helping out

If you'd like to help out, great!  The TODO file contains a small list.

If you port this code to other architectures, please share your changes
so others can benefit.

Please use diff -u or CVS (see below) to prepare patches.

* CVS

You can use CVS to keep your local copy up-to-date as we make 
changes and fix bugs.  See the cvs(1) man page here ("9 man cvs")
for details on using cvs.

* Contact

Russ Cox <rsc@swtch.com>
Languages
C 91.6%
Roff 1.4%
C++ 1.3%
Yacc 1.2%
Shell 1.2%
Other 3%