Page 1 of 1

Why does this not cause an overflow?

PostPosted: Sat Jan 19, 2013 8:39 pm
by -Ninjex-
So I just started C++ and hit the point reading about overflows. I was curious of how overflows worked, and started messing wih them. I made the code below and I was curious of why it does not produce an overflow.
Below we make x = to 65535, in the first expression, we add 1 to x giving us 65536 which equals 1 0000 0000 0000 0000 in binary, making it wrap around and cause a overflow and now x will = zero. In the second expression we take the same variable x which now equals 65536 but prints as if x is = to 0, and then we subtract the 65535 from it and add it right back. x then prints out 65536.
I am a bit newer to this, could anyone explain why the second expression does not give an overflow?

Code: Select all
#include <iostream>

int main()
{
    using namespace std;
    unsigned short x = 65535; // largest 2-byte unsigned value possible
    cout << "x was: " << x << endl;
    x = x + 1;        //We add 1 to 65535 which gives an overflow.
    cout << "x is now: " << x << endl;
    //Subctract 66535 from x and then add it back to x
    cout << "Bypass the overflow: "; x = x - 65535; cout << x + 65535; cout << endl;
}

Re: Why does this not cause an overflow?

PostPosted: Sat Jan 19, 2013 9:14 pm
by fashizzlepop
Are you on a 64bit machine?

Note: it may not even be dependent on your data model and depends mostly on the implementation (compiler).

Re: Why does this not cause an overflow?

PostPosted: Sat Jan 19, 2013 9:27 pm
by -Ninjex-
fashizzlepop wrote:Are you on a 64bit machine?

Note: it may not even be dependent on your data model and depends mostly on the implementation (compiler).


32bit System

Code: Select all
$ uname -a
Linux Ninjex 3.2.0-35-generic-pae #55-Ubuntu SMP Wed Dec 5 18:04:39 UTC 2012 i686 athlon i386 GNU/Linux


g++ is what I use to compile I used the following syntax from g++

Code: Select all
g++ test.cpp -o test

Code: Select all
$ ./test
x was: 65535
x is now: 0
Bypass the overflow: 65536


Re: Why does this not cause an overflow?

PostPosted: Sat Jan 19, 2013 9:29 pm
by fashizzlepop
So... It worked?

Re: Why does this not cause an overflow?

PostPosted: Sat Jan 19, 2013 9:30 pm
by -Ninjex-
fashizzlepop wrote:So... It worked?


Yes, I do not understand how dropping 65535 and adding it back to 65536 makes it print out 65536 after it previously printed 0

For instance:

x = 65535
//printed as 65535

x + 1 = 65536
//printed as 0

x - 65535; x + 65535 = 65536
//printed as 65536

Re: Why does this not cause an overflow?

PostPosted: Sat Jan 19, 2013 9:33 pm
by tgoe
https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules

tldr: magic

LOL

compare these two C programs:

Code: Select all
#include <stdio.h>

int main(void) {
    unsigned short x = 65535;
    printf("x was: %d\n", x);
    x = x + 1;
    printf("x is now: %d\n", x);
    x = x - 65535;
    printf("Bypass the overflow: %d\n", x + 65535);
    return 0;
}


Code: Select all
#include <stdio.h>

int main(void) {
    unsigned short x = 65535;
    printf("x was: %d\n", x);
    x = x + 1;
    printf("x is now: %d\n", x);
    x = x - 65535;
    x = x + 65535;
    printf("Bypass the overflow: %d\n", x);
    return 0;
}

Re: Why does this not cause an overflow?

PostPosted: Sat Jan 19, 2013 9:42 pm
by -Ninjex-
Thanks for the help...
You are a saver Tgoe!

I removed the code blocks to allow the colour code to show my mistake.

-- Sat Jan 19, 2013 9:55 pm --

tgoe wrote:#include <stdio.h>

int main(void) {
unsigned short x = 65535;
printf("x was: %d\n", x);
x = x + 1;
printf("x is now: %d\n", x);
x = x - 65535;
printf("Bypass the overflow: %d\n", x + 65535);
return 0;
}





#include <stdio.h>

int main(void) {
unsigned short x = 65535;
printf("x was: %d\n", x);
x = x + 1;
printf("x is now: %d\n", x);
x = x - 65535;
x = x + 65535
;
printf("Bypass the overflow: %d\n", x);
return 0;
}


The second code calls for the expressions outside of the print statement
This works for namespace std

#include <iostream>

int main()
{
using namespace std;
unsigned short x = 65535; // largest 2-byte unsigned value possible
cout << "x was: " << x << endl;
x = x + 1; // We desire 65536, but we get overflow!
cout << "x is now: " << x << endl;
x -= 65535; x += 65535;
cout << "This will have the same result: ";
cout << x;
cout << endl;
}


#facepalm