I'm working on a project to update 20 year old code, and many of the issues have to do with integer overflow. I wanted to make sure I was testing for overflow correctly, so I wrote a test program. It's output supprised me. Here it is:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
int main (void) {
size_t largerNum,Num;
largerNum = 12;
Num = UINT_MAX;
printf("largerNum = %u\nNum = %u\nNum + 1 = %u\n", largerNum , Num, Num + 1);
largerNum = Num + 1;
printf("largerNum now = %u\n", largerNum);
if(largerNum < Num ){
printf("largerNum overflowed to %u\n", largerNum);
}
else {
printf("largerNum did not overflow: %u\n", largerNum);
}
printf("Is (0 < UINT_MAX)?\n");
(0 < UINT_MAX)?printf("YES\n"):printf("NO\n");
printf("Is (largerNum < Num)?\n");
(largerNum < Num)?printf("YES\n"):printf("NO\n");
return 0;
}
And its output:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 0
largerNum did not overflow: 0
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
NO
I've looked at some other posts here and here and read this paper, but it has not made the output anymore clear. Anyone see this before?
Edit: I got it to work when changing from size_t
to unsigned long
, which shouldn't do anything.
6 int main (void) {
7
8 unsigned long largerNum,Num;
9
10 largerNum = 12;
11 Num = UINT_MAX;
12
13 printf("largerNum = %u\nNum = %u\nNum + 1 = %u\n", largerNum , Num, Num + 1);
14
15 largerNum = Num + 2;
16
17 printf("largerNum now = %u\n", largerNum);
18
19 if(largerNum < Num ){
20 printf("largerNum overflowed to %u\n", largerNum);
21 }
22 else {
23 printf("largerNum did not overflow: %u\n", largerNum);
24 }
25
26 printf("Is (0 < UINT_MAX)?\n");
27
28 (0 < UINT_MAX)?printf("YES\n"):printf("NO\n");
29
30 printf("Is (largerNum < Num)?\n");
31
32 (largerNum < Num)?printf("YES\n"):printf("NO\n");
33
34
35 printf("largerNum = %u\n", largerNum);
36 printf("Num = %u\n", Num);
37
38 return 0;
39 }
Output:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 4294967295
Edit2:
Upon reading some comments, I substituted 'UINT_MAX' for 'ULONG_MAX', and the ternary operators functioned correctly. I then changed 'size_t' to 'unsigned long'. and it still works correctly. What is odd to me is that on my machine, 'size_t', 'unsigned int', and 'unsigned long' are all the same number of bytes, and 'UINT_MAX' and 'ULONG_MAX' are the same value, yet that ternary operator would still fail despite everything being the same. Maybe it's not the same? This upsets my understanding of C.
For those interested, the working code:
6 int main (void) {
7 /* Can be size_t or unsigned long */
8 size_t largerNum,Num;
9
10 largerNum = 12;
11 Num = ULONG_MAX;
12
13 printf("largerNum = %u\nNum = %u\nNum + 1 = %u\n", largerNum , Num, Num + 1);
14
15 largerNum = Num + 2;
16
17 printf("largerNum now = %u\n", largerNum);
18
19 if(largerNum < Num ){
20 printf("largerNum overflowed to %u\n", largerNum);
21 }
22 else {
23 printf("largerNum did not overflow: %u\n", largerNum);
24 }
25
26 printf("Is (0 < ULONG_MAX)?\n");
27
28 (0 < ULONG_MAX)?printf("YES\n"):printf("NO\n");
29
30 printf("Is (largerNum < Num)?\n");
31
32 (largerNum < Num)?printf("YES\n"):printf("NO\n");
33
34
35 printf("largerNum = %u\n", largerNum);
36 printf("Num = %u\n", Num);
37
38 return 0;
39 }
Output:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < ULONG_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 4294967295
Final Edit:
After reading more comments, I found that my printf()
statements were wrong. Thank you all for your help, and everything makes way more sense now. =D
Final code:
6 int main (void) {
7
8 unsigned long largerNum,Num;
9
10 largerNum = 12;
11 Num = ULONG_MAX;
12
13 printf("largerNum = %zu\nNum = %zu\nNum + 1 = %zu\n", larger Num, Num, Num + 1);
14
15 largerNum = Num + 2;
16
17 printf("largerNum now = %zu\n", largerNum);
18
19 if(largerNum < Num ){
20 printf("largerNum overflowed to %zu\n", largerNum);
21 }
22 else {
23 printf("largerNum did not overflow: %zu\n", largerNum);
24 }
25
26 printf("Is (0 < ULONG_MAX)?\n");
27
28 (0 < ULONG_MAX)?printf("YES\n"):printf("NO\n");
29
30 printf("Is (largerNum < Num)?\n");
31
32 (largerNum < Num)?printf("YES\n"):printf("NO\n");
33
34
35 printf("largerNum = %zu\n", largerNum);
36 printf("Num = %zu\n", Num);
37
38 return 0;
39 }
Final Output:
[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 18446744073709551615
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < ULONG_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 18446744073709551615