Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

uint64_t t3 = MAXDWORD + 1 == 0?

Tags:

c++

I really don't understand what is happening with the code below. Why is t3 zero?

uint64_t t1 = MAXDWORD;         // t1 contains 4294967295 - CORRECT
uint64_t t2 = t1 + 1;           // t2 contains 4294967296 - CORRECT
uint64_t t3 = MAXDWORD + 1;     // t3 contains 0 (zero)   - HUH??
like image 763
Ben Avatar asked Dec 07 '22 13:12

Ben


2 Answers

decltype(MAXDWORD) is a narrower type than uint64_t. So the expression MAXDWORD + 1 is not a uint64_t either, and unsigned wraparound behaviour is observed prior to the assignment to t3.

t1 + 1 is performed in unsigned arithmetic using the uint64_t type, which is wider.

like image 69
Bathsheba Avatar answered Jan 04 '23 00:01

Bathsheba


In this case I think that MAXDWORD is 32 bit and not 64 bit since 4294967295 is the max size of a 32 bit unsigned integer. Therefore the expression MAXDWORD + 1 is the sum of two 32 bit values which is only upgraded to 64 bit after evaluation. Therefore it will overflow back to zero.

t1 + 1 on the other hand is a 64 bit and a 32 bit expression. The 32 bit constant is upgraded to 64 bits and then evaluated. This therefore does not overflow.

Give the bellow expressions a try and see if you can figure out which ones will overflow...

uint64_t t4 = MAXDWORD + 1LL;
uint64_t t5 = (uint64_t)MAXDWORD + 1;
uint64_t t6 = MAXDWORD + (uint64_t)1;
uint64_t t7 = (uint64_t)(MAXDWORD + 1);
like image 37
chasep255 Avatar answered Jan 04 '23 00:01

chasep255