using signed int for values that should never be negative

This topic is 4024 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

The game engine my company has licensed does this all the time - it will use signed math for a simple for loop. It seems to me that this is bad practice and can, in some circumstances, result in severe security vulnerabilities. Should I always be using unsigned types for types that are never negative, or am I overreacting and adding complexity where it is completely unnecessary?

Share on other sites
I have one question for you to consider. When is 4294967295 preferable to -1 when it comes to invalid values?

Share on other sites
I wouldn't say that using signed integers for values that will never be negative is bad practice as such, it's certainly quite common practice and you can use -1 to represent an uninitialised state which can be handy.

I personally however do use unsigned ints quite extensively, like: for (unsigned int i = 0; i < something; ++i)

If I see a signed integer I don't automatically assume it'll be used for negative values but the possibility exists, if I see an unsigned integer then I know it will always be positive, being explicit about your intentions never hurts.

Ofcourse, signed integers usually have a lower maximum (positive) range than an unsigned integer, so sometimes the decision is effectively made for you based on what you need.

Share on other sites
Quote:
 Original post by PromitI have one question for you to consider. When is 4294967295 preferable to -1 when it comes to invalid values?

I think he might be asking this:
for (int i = 0; i < 10; i++) {  a = i; <-- array index cannot be negative in a sane application};

Personally, I try to match signedness with context.

Using unsigned types isn't always just gravy, and I had to deal with a very nasty side-effect of it.

The loop as simple:
size_t MAX = (a - b);size_t i = 0;while ( i < MAX ) // do something

But... due to various circumstances, MAX was initialized to -1, and hilarity ensued. If signed types were allowed, negative values would properly terminate the loop.

So it's not a sure-fire way to solve or prevent bugs.

There was also another conflict I encounter.

While designing a Buffer class, I chose STL's types. Size was size_t, since buffer size is either 0 or positive number.

But then I used pointer difference to obtain used size (curr_ptr - begin_ptr), which is typed as ptrdiff_t. Obviously, ptrdiff_t is signed, although.

Here's where compiler was hinting at something - even if I design a class correctly, and make sure it works, the language no longer guarantees that pointers are truly properly initialized.

So if compiler is warning you about sign conversions, it's usually a sign you're avoiding something, or trying to make something messy. In my case, it was perfectly warranted, since I was deliberately mixing incompatible types, even though I was trying to be smart about it.

Use whatever you see fit. But make sure you take into consideration the warnings compiler might start issuing over your choices. They'll usually expose very subtle situations.

Share on other sites
for (int i = 0; i < 10; i++) {  a = i; <-- array index cannot be 4 billion in a sane application either.};

Share on other sites
This is a personal view and obviously not widespread in use (as judged from the posts here) but I always try to use the sign according to context. So if a loop should not be negative then unsigned will be used; if a generated random value should be positive then I'll use unsigned, etc (actually this issue of signed and unsigned becomes absolutely critical within some pseudo-random number generator algorithms). I feel it is just good practice to be aware of the allowable or expected limits of all parts of the code no matter how small, and to code accordingly.

--random

Share on other sites
Quote:
 Original post by Sneftelfor (int i = 0; i < 10; i++) { a = i; <-- array index cannot be 4 billion in a sane application either.};

er, why would i be 4 billion, and why would having i be -1 make a difference?

Share on other sites
Quote:
 Original post by random_thinkerThis is a personal view and obviously not widespread in use (as judged from the posts here) but I always try to use the sign according to context. So if a loop should not be negative then unsigned will be used; if a generated random value should be positive then I'll use unsigned, etc (actually this issue of signed and unsigned becomes absolutely critical within some pseudo-random number generator algorithms). I feel it is just good practice to be aware of the allowable or expected limits of all parts of the code no matter how small, and to code accordingly.--random

I think to some extent this can be bad - for example, using a char to represent an ascii value is fine, but chances are it just means 3 bytes are wasted because everything is int-aligned.

Share on other sites
using signed in a for loop is totally normal. Not a "security risk". I once tried to do this but then you end up using the value to pass into a function which expects signed int, and end up with a nasty mess of casts.

int is the simple and the default thing to use, whenever you don't have extremely large values to deal with (or bitmasks).

Share on other sites
Quote:
Original post by thedustbustr
Quote:
 Original post by Sneftelfor (int i = 0; i < 10; i++) { a = i; <-- array index cannot be 4 billion in a sane application either.};

er, why would i be 4 billion, and why would having i be -1 make a difference?

The point is that unsigned values cause bugs and vulnerabilities in exactly the same places as signed values. The computer doesn't do the range checking for you either way.

1. 1
2. 2
3. 3
Rutin
19
4. 4
5. 5
JoeJ
12

• 14
• 22
• 9
• 31
• 17
• Forum Statistics

• Total Topics
632617
• Total Posts
3007470
• Who's Online (See full list)

There are no registered users currently online

×