Is it bad to underflow then overflow an unsigned variable?

1.7k views Asked by At

Kraaa.

I am a student in a programming school who requires us to write C functions with less than 25 lines of code. So, basically, every line counts. Sometimes, I have the need to shorten assignments like so:

#include <stddef.h>
#include <stdio.h>

#define ARRAY_SIZE  3

int     main(void)
{
    int     nbr_array[ARRAY_SIZE] = { 1, 2, 3 };
    size_t  i;

    i = -1;
    while (++i < ARRAY_SIZE)
        printf("nbr_array[%zu] = %i\n", i, nbr_array[i]);
    return (0);
}

The important part of this code is the size_t counter named i. In order to save up several lines of code, I would like to pre-increment it in the loop's condition. But, insofar as the C standard defines size_t as an unsigned type, what I am basically doing here, is underflowing the i variable (from 0 to a very big value), then overflowing it once (from that big value to 0).

My question is the following: regardless of the bad practises of having to shorten our code, is it safe to set an unsigned (size_t) variable to -1 then pre-increment it at each iteration to browse an array?

Thanks!

3

There are 3 answers

2
Pascal Cuoq On BEST ANSWER

The i = -1; part of your program is fine.

Converting -1 to an unsigned integer type is defined in C, and results in a value that, if incremented, results in zero.

This said, you are not gaining any line of code with respect to the idiomatic for (i=0; i<ARRAY_SIZE; i++) ….

Your %zi format should probably be %zu.

0
Cornstalks On

Unsigned arithmetic never "overflows/underflows" (at least in the way the standard talks about the undefined behavior of signed arithmetic overflow). All unsigned arithmetic is actually modular arithmetic, and as such is safe (i.e. it won't cause undefined behavior in and of itself).

4
cmaster - reinstate monica On

To be precise, the C standard guarantees two things:

  • Any integer conversion to an unsigned type is well defined (as if the signed number were represented as 2-complement)
  • overflow/underflow of unsigned integers is well defined (modular arithmetic with 2^n)

Since size_t is an unsigned type, you are not doing anything evil.