

The problem with -2147483648 in C.  - jodoherty
http://www.hardtoc.com/archives/119

======
haberman
This bit of asymmetry also leads to this interesting security implication:
<http://my.opera.com/taviso/blog/show.dml/639454>

(In short, (INT_MIN / -1) can crash your program with an exception, since the
result can't be represented in an integer. It's an easy way to crash a program
that does integer math on untrusted input.

~~~
ajross
Um... what? That produces no exception on any architecture I know. In 2's
complement, -INT_MIN == INT_MIN. It certainly can be represented in an
integer, and it's perfectly legal to return -2147483648 from that division,
and the machine in front of me certainly does.

Integer math is done modulo 2^n (with a -2^(n-1) offset for signed operations)
on modern hardware. Overflow is part of the design. There are no exceptions
defined for results that "can't be represented". Divide by zero aborts because
the underlying mathematical concept doesn't exist; that's different from a
mere overflow.

Obviously there can be bugs that can result from an overflow, but overflow
bugs are hardly limited to INT_MIN.

~~~
haberman
> Um... what? That produces no exception on any architecture I know.

Have you tried actually compiling and running Tavis's test program with the
given arguments? I did and it crashed on my Core i7 running on OS X.

In gdb I get:

    
    
        (gdb) run -2147483648 -1
        Starting program: /private/tmp/test3 -2147483648 -1
        Reading symbols for shared libraries +. done
    
        Program received signal EXC_ARITHMETIC, Arithmetic exception.
        0x0000000100000f23 in main ()
    

Hint: it won't work to just compile a program that does INT_MIN / -1 at
compile-time, the compiler will do constant-folding that prevents an actual
"idiv" instruction from being generated.

~~~
ajross
Ooh, my bad. Though I was actually smarter than that and made gcc (4.6.0,
amd64) do the division. The problem is that "int a=0x80000000; printf("%d\n",
a/-1);" when compiled without (!) optimization generates a NEG instruction,
not an IDIV.

That's not constant folding, that's strength reduction. And it's an
optimization that I specifically told gcc not to do. Honestly I'd consider
this a compiler bug. And of course NEG does what I expected and produces the
2's complementation negation of 0x8000000 (which is 0x80000000).

------
ScottBurson
I pity all you benighted knaves who still labor with bounded-precision
integers. Lisp has tried to show you the True Way for decades now, but you
have not listened! Unbounded-precision integers would free you from your
chains!

(Obviously tongue-in-cheek... mostly... :-)

~~~
marshray
If Giuseppe Peano had not handed down to us unbounded precision integers, it
would have been necessary for John McCarthy to invent them.

Why?

To count all those freakin parentheses! HAHAHAHAHAA!

