views:

727

answers:

6

So I hear a lot of opinions about this, and I wanted to see if there was anything resembling a consensus. When is it appropriate to use an unsigned variable over a signed one? What about in a for loop?

for (unsigned int i = 0; i < someThing.length(); i++) {  
SomeThing var = someThing.at(i);
// You get the idea.
}

As I said, I hear a lot of opinions, but not a lot of consensus. I know Java doesn't have unsigned values, and that must have been a concious decision on Sun's part.

Looking forward to hearing everybody's opinion.

+10  A: 

I was glad to find a good conversation on this subject, as I hadn't really given it much thought before.

In summary, signed is a good general choice - even when you're dead sure all the numbers are positive - if you're going to do arithmetic on the variable (like in a typical for loop case).

If you're going to do bitwise things like masks, unsigned starts to make more sense. Or, if you're desperate to get that extra positive range by taking advantage of the sign bit.

Personally, I like signed because I don't trust myself to stay consistent and avoid mixing the two types (like the article warns against).

saint_groceon
A: 

In your example above, when 'i' will always be positive and a higher range would be beneficial, unsigned would be useful. Like if you're using 'declare' statements, such as:

#declare BIT1 (unsigned int 1)
#declare BIT32 (unsigned int reallybignumber)

Especially when these values will never change.

However, if you're doing an accounting program where the people are irresponsible with their money and are constantly in the red, you will most definitely want to use 'signed'.

I do agree with saint though that a good rule of thumb is to use signed, which C actually defaults to, so you're covered.

contagious
A: 

size_t is often a good choice for this, or size_type if you're using an STL class.

Mark Harrison
A: 

C and C++ compilers will generate a warning when you compare signed and unsigned types; in your example code, you couldn't make your loop variable unsigned and have the compiler generate code without warnings (assuming said warnings were turned on).

Naturally, you're compiling with warnings turned all the way up, right?

And, have you considered compiling with "treat warnings as errors" to take it that one step further?

The downside with using signed numbers is that there's a temptation to overload them so that, for example, the values 0->n are the menu selection, and -1 means nothing's selected - rather than creating a class that has two variables, one to indicate if something is selected and another to store what that selection is. Before you know it, you're testing for negative one all over the place and the compiler is complaining about how you're wanting to compare the menu selection against the number of menu selections you have - but that's dangerous because they're different types. So don't do that.

Josh
A: 

Naturally, you're compiling with warnings turned all the way up, right?

And, have you considered compiling with "treat warnings as errors" to take it that one step further?

I do with my own code, but when working with other people's stuff nothing would ever compile. My example was contrived, I used to be fairly inconsistent, but I generally stick to "when in doubt, use signed".

Bernard
A: 

I would think that if your Business Case dictates that a negative number is invalid, you would want to have an error shown or thrown.

With that in mind, I only just recently found out about unsigned integers while working on a project processing data in a binary file and storing the data into a database. I was purposely "corrupting" the binary data, and ended up getting negative values instead of an expected error. I found that even though the value converted, the value was not valid for my business case.
My program did not error and I ended up getting wrong data into the database. It would have been better if I had used uint and had the program fail.

Keith

Keith Sirmons