Re: Tell me why an integer overflow should crash my show, god damn it ! by Victor
Victor
Fri Aug 03 20:07:36 CDT 2007
Ben Voigt [C++ MVP] wrote:
> "Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
> news:f8smgd$5p9$1@news.datemas.de...
>> Ben Voigt [C++ MVP] wrote:
>>> "Victor Bazarov" <v.Abazarov@comAcast.net> wrote in message
>>> news:f8r1rt$ser$1@news.datemas.de...
>>>> Ben Voigt [C++ MVP] wrote:
>>>>>> Tell me why an integer overflow should crash my show, god damn
>>>>>> it ! I'd really love to know. Why yer at it, tell me why an
>>>>>> underflow, e.g. zero, doesn't do the same thing.
>>>>>
>>>>> Neither integer overflow nor underflow crash. This is overflow:
>>>>>
>>>>> unsigned u = ~0; // a very very big number
>>>>> ++u; // overflowed to zero
>>>>
>>>> No, it isn't, at least in C++. Operations on 'unsigned int' are
>>>> different from operations on 'int'. The result of arithmetic ops
>>>> for 'unsigned' are always mod 2^n where 'n' is the number of bits
>>>> in the representation (see [basic.fundamental]/4 and the footnote).
>>>
>>> That doesn't mean it isn't overflow. It means that behavior during
>>> overflow is well documented.
>>
>> Yes, it does mean "no overflow". The footnote 41 in the Standard
>> circa 2003 says "This implies that unsigned arithmetic does not
>> overflow because ...". I read it as "unsigned arithmetic does NOT
>> overflow". To me it means "no overflow". Am I missing something?
>
> I don't know. I would have phrased that more like "unsigned
> arithmetic overflow is not exceptional".
>
> This is getting kinda Kerry-esque: it overflowed before it didn't
> overflow. The operation overflowed, wrapping around and producing a
> result in the range of the variable. Since the result is in range,
> there is no overflow.
> Certainly a lot of the "integer overflow" class of attacks occur with
> unsigned types. Also I believe that the "carry/overflow" bit will be
> set in the CPU for most any instruction set following that statement.
Yes, the carry bit is set. The emitted code doesn't care about it and
there is no way except inline assembly to actually get at it, and I do
not know a reliable way to do so, either.
bool overflowed(unsigned a, unsigned b)
{
bool rv = false;
unsigned ab = a + b;
__asm {
jnc nocarry
mov rv, 1
nocarry:
}
return rv;
}
int main()
{
bool should = overflowed(-1, 2);
bool shouldnot = overflowed(1, 2);
return should + shouldnot;
}
This does work correctly built in debug mode, but fails in release,
which is not unexpected.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask