How to safely compare two unsigned integer counters?

  • A+

We have two unsigned counters, and we need to compare them to check for some error conditions:

uint32_t a, b; // a increased in some conditions // b increased in some conditions if (a/2 > b) {    perror("Error happened!");    return -1; } 

The problem is that a and b will overflow some day. If a overflowed, it's still OK. But if b overflowed, it would be a false alarm. How to make this check bulletproof?

I know making a and b uint64_t would delay this false-alarm. but it still could not completely fix this issue.


Let me clarify a little bit: the counters are used to tracking memory allocations, and this problem is found in dmalloc/chunk.c:

#if LOG_PNT_SEEN_COUNT   /*    * We divide by 2 here because realloc which returns the same    * pointer will seen_c += 2.  However, it will never be more than    * twice the iteration value.  We divide by two to not overflow    * iter_c * 2.    */   if (slot_p->sa_seen_c / 2 > _dmalloc_iter_c) {     dmalloc_errno = ERROR_SLOT_CORRUPT;     return 0;   } #endif 


Dont use plain counters but wrap them in a class:

class check {     unsigned a = 0;     unsigned b = 0;     bool odd = true;     void normalize() {         auto m = std::min(a,b);         a -= m;         b -= m;     } public:     void incr_a(){          if (odd) ++a;         odd = !odd;         normalize();     }     void incr_b(){          ++b;         normalize();     }     bool check() { return a > b;} } 

Note that to avoid the overflow completely you have to take additional measures, but if a and b are increased more or less the same amount this might be fine already.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: