Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with unsigned integers

I know that unsigned integers are infamous and generally avoided by C++ devs. I have a class with two int member variables that should not contain negative values:

.
.
.
private:
    int m_Y_AxisLen;
    int m_X_AxisLen;
.
.
.

I have designed the logic of the member functions in a way that prevents any input of negative numbers. So I have made sure that those two members won't be assigned negative values.
But this also brings up some warnings when I use PVS-Studio. For example here:

for ( int row = 0; row < getY_AxisLen( ); ++row )
{
    for ( int column = 0; column < getX_AxisLen( ) - 1; ++column )
    {
        if ( m_characterMatrix[ row ][ column ] == getFillCharacter( ) )
        {
            m_characterMatrix[ row ][ column ] = fillCharacter;
        }
    }
}

PVS-Studio blames me for the indices row and column not being of memsize type. It probably means that I should have used std::size_t row and std::size_t column??
But if I had done it that way then it would still complain and say that comparing unsigned integral type with getY_AxisLen( ) (which returns an int) is dangerous.
So this is the reason that I want to rewrite parts of my class to switch to this:

private:
    uint32_t m_Y_AxisLen;
    uint32_t m_X_AxisLen;

I am humbly looking for insights and advice from professionals who have dealt with these kinds of problems before. What would be your approach when it comes to these issues?

like image 547
digito_evo Avatar asked Dec 21 '21 08:12

digito_evo


People also ask

How do you represent an unsigned integer?

The unsigned integer is represented by an unsigned binary number whose most significant byte is 0; the least significant is 3.

What is the point of unsigned integer?

Unsigned integers are used when we know that the value that we are storing will always be non-negative (zero or positive). Note: it is almost always the case that you could use a regular integer variable in place of an unsigned integer.

What is a unsigned integer example?

The simplest numbers that we want to represent in the machine are the unsigned integers. These are whole numbers without a sign, for example, 0, 1, 2, 3, … The mechanical calculators of yesteryear and the car mileage meter of today both store unsigned integers on what are effectively cogs having ten numbered teeth1.

What happens if you put a negative number in an unsigned int?

You simply cannot assign a negative value to an object of an unsigned type. Any such value will be converted to the unsigned type before it's assigned, and the result will always be >= 0.


1 Answers

A lot of those "you shouldn't use unsigned integers" are just basically scared that you will mix up signed integers and unsigned ones, causing a wrap-around, or to avoid complex integer promotion rules.

But in your code, I see no reason not to use uint32_t and std::size_t, because m_X_AxisLen and m_Y_AxisLen should not contain negative values, and using uint32_t and std::size_t makes a lot more sense here:

So, I suggest changing m_X_AxisLen and m_Y_AxisLen to:

std::size_t m_Y_AxisLen;
std::size_t m_X_AxisLen; // for consistency

Change row and column to

std::size_t row = 0;
// and 
std::size_t column = 0;

Make getX_AxisLen( ) returns an std::size_t

And make the for loop:

for ( int column = 0; column < getX_AxisLen( ) - 1; ++column )

to:

for ( int column = 0; column + 1 < getX_AxisLen( ); ++column )

Because if getX_AxisLen() returns 0, getX_AxisLen( ) - 1 will cause a wrap-around.

Basically, use the thing that makes sense. If a value cannot be negative, use the unsigned type.

like image 115
justANewb stands with Ukraine Avatar answered Sep 29 '22 09:09

justANewb stands with Ukraine