Underflow

Here is a simple code I just recently found a bug* in.

void derp(size_t n, int* A, int* B, int* C){
    for(; n--; A++, B++, C++){
        *A = *B + *C;
    }
 }

Let's disregard all theoretical problems, that *B+*C might overflow, null pointer accesses or out-of-bounds access. The actual bug* is that n-- might underflow!

By definition, n is an positive unsigned integer. The loop counts down until n is 0. To be precise, n is 0 at the end of of an iteration and then we jump back up. Next the processor checks n > 0, which fails. After that the n-- kicks in. Only after that the function returns.

So n-- can underflow and it actually happens and can be detected by tools such as the clang integer sanitizer. We are lucky that underflows for unsigned datatypes are well-defined; they just wrap around. I still think, that this is unexpected behaviour. To fix it, move the decrement into the iteration and just check for n>0.

void derp( size_t n, int* A, int* B, int* C){
   for( ; n; n--, A++, B++, C++){
       *A = *B + *C;
   }
}