Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I believe some logic behind may be that you can't recognize an overflow has happened with unsigned, but with signed you can recognize over and underflows in certain cases by simply checking if it's a non-negative number.

At least I believe Java decided on signed integers for similar reasons. But if it's indeed UB in C++, it doesn't make sense.



Gosling on the matter,

> One of the little experiments I tried was asking people about the rules for unsigned arithmetic in C. It turns out nobody understands how unsigned arithmetic in C works. There are a few obvious things that people understand, but many people don't understand it.

-- https://www.artima.com/articles/james-gosling-on-java-may-20...



It’s the opposite in cpp: unsigned integer overflow is undefined but signed overflow is defined as wrapping


No, it's the opposite. UNSIGNED overflow wraps around. SIGNED overflow is undefined behavior.

This leads to fun behavior. Consider these functions which differ only in the type of the loop variable:

    int foo() {
        for (int i = 1; i > 0; ++i) {}
        return 42;
    }
    
    int bar() {
        for (unsigned i = 1; i > 0; ++i) {}
        return 42;
    }
If you compile these with GCC with optimization enabled, the result is:

    foo():
    .L2:
        jmp     .L2

    bar():
        mov     eax, 42
        ret
That is, foo() gets compiled into an infinite loop, while the loop in bar() is eliminated instead. This is because the compiler may assume only in the first case that i will never overflow.


Did you mix up unsigned and signed by mistake? Because in C and C++, the wrapping one is unsigned and the here-be-dragons-on-overflow one is signed.


Oh jeeze. I can’t believe I flipped that. I find myself wishing I could delete my comment.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: