Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsigned integers in C++ for loops

I have made some research on Stackoverflow about reverse for loops in C++ that use an unsigned integer instead of a signed one. But I still do NOT understand why there is a problem (see Unsigned int reverse iteration with for loops). Why the following code will yield a segmentation fault?

#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    vector<double> x(10);

    for (unsigned int i = 9; i >= 0; i--)
    {
        cout << "i= " << i << endl;
        x[i] = 1.0;
    }

    cout << "x0= " << x[0] << endl;

    return 0;
}

I understand that the problem is when the index i will be equal to zero, because there is something like an overflow. But I think an unsigned integer is allowed to take the zero value, isn't it? Now if I replace it with a signed integer, there is absolutely no problem.

Does somebody can explain me the mechanism behind that reverse loop with an unsigned integer?

Thank you very much!

like image 489
Benjamin Avatar asked Jan 28 '12 08:01

Benjamin


People also ask

What is an unsigned integer in C?

An unsigned Integer means the variable can hold only a positive value. This format specifier is used within the printf() function for printing the unsigned integer variables.

How are unsigned integers stored in C?

In C programming language, unsigned data type is one of the type modifiers which are used for altering the data storage of a data type. In C, usually, we have integer (int) data type by default are signed where it can store values both negative and positive values.

Should you use unsigned ints?

The Google C++ style guide recommends avoiding unsigned integers except in situations that definitely require it (for example: file formats often store sizes in uint32_t or uint64_t -- no point in wasting a signedness bit that will never be used).

How do you represent unsigned int?

The signed integer is represented in twos complement notation. The most significant byte is 0 and the least significant is 3. The unsigned integer is represented by an unsigned binary number whose most significant byte is 0; the least significant is 3. See the Signed Integer and Unsigned Integer figure (Figure 1).


1 Answers

The problem here is that an unsigned integer is never negative.

Therefore, the loop-test:

i >= 0

will always be true. Thus you get an infinite loop.

When it drops below zero, it wraps around to the largest value unsigned value.
Thus, you will also be accessing x[i] out-of-bounds.

This is not a problem for signed integers because it will simply go negative and thus fail i >= 0.

Thus, if you want to use unsigned integers, you can try one of the following possibilities:

for (unsigned int i = 9; i-- != 0; )

and

for (unsigned int i = 9; i != -1; i--)

These two were suggested by GManNickG and AndreyT from the comments.


And here's my original 3 versions:

for (unsigned int i = 9; i != (unsigned)0 - 1; i--)

or

for (unsigned int i = 9; i != ~(unsigned)0; i--)

or

for (unsigned int i = 9; i != UINT_MAX; i--)
like image 86
Mysticial Avatar answered Oct 12 '22 14:10

Mysticial