Jump to content
  • Advertisement
Sign in to follow this  
thedustbustr

using signed int for values that should never be negative

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

If you intended to correct an error in the post then please contact us.

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 this post


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

Share this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Promit
I 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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
for (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 this post


Link to post
Share on other sites
Quote:
Original post by random_thinker
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

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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by thedustbustr
Quote:
Original post by Sneftel
for (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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!