
Ways C compilers break for objects larger than PTRDIFF_MAX bytes - panic
http://trust-in-soft.com/objects-larger-than-ptrdiff_max-bytes/
======
zamalek
Results from VC++ (VS2015 Update 2):

\- 32-bit, demo 1: -268435456

\- 32-bit, demo 2: 0

\- 64-bit, demo 3:

    
    
        warning C4034: sizeof returns 0
        error C2036: 'arrayptr': unknown size

------
derefr
I always figured this (or an equivalent problem with mmap(3)) was what was
behind Erlang's DETS filesize limit.

------
userbinator
_Strange results are acceptable because the overflow in pointer subtractions
is undefined behavior_

The first example, with -2130706432, is not strange at all and there doesn't
appear to be any exploiting of UB, since that is just 0x81000000 interpreted
as a signed number; it's the following examples that really show the oddness
caused by the signedness of the type.

That 64-bit example, however, is IMHO a bug --- I doubt the system he ran it
on has anywhere near the 14 _exabytes_ of RAM he asked for, so malloc()
succeeding in that case is ridiculous.

~~~
unwind
In C, 0x81000000 is always a signed number, since that's a regular "int"-type
literal (like "17"). Whether it's negative or not is of course implementation-
dependent, on a 32-bit system with 32-bit "int" it will be since bit 31 is
set.

To make it unsigned you'd have to append an 'u'.

I'm sure you know this, but people somehow sometimes seem to magically expect
"certain" literals to be unsigned just because they're hex, and that's not how
it works.'

EDIT: It seems I forgot about the complexities pointed out by replies to this
comment. Thanks. Now the only think I'm certain about is that I'm confused.

~~~
cremno
That's not true. Hexadecimals integer constants without suffix may have a
signed type but they also may have an unsigned one. For example, 0x81000000
usually has type unsigned int.

[http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5](http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5)

~~~
ryao
Passing %d to printf says to print an int. 0x81000000 is a negative number
when processed as a 32-bit signed integer. The output is the two's complement
interpretation of the value. To print an unsigned int, you should pass %u.
This would be more obviously correct if %x were used to print the hexadecimal
representation, which is 0x81000000.

------
jwilk
If the site showed anything beyond red bouncing balls, I'd so happy. And no,
I'm not going to enable JS in my browser.

~~~
marcoperaza
No HackerNews thread is complete without someone complaining about JS on the
website.

