This is a rather silly question but why is int
commonly used instead of unsigned int
when defining a for loop for an array in C or C++?
<
I use int
cause it requires less physical typing and it doesn't matter - they take up the same amount of space, and unless your array has a few billion elements you won't overflow if you're not using a 16-bit compiler, which I'm usually not.
Because unless you have an array with size bigger than two gigabyts of type char
, or 4 gigabytes of type short
or 8 gigabytes of type int
etc, it doesn't really matter if the variable is signed or not.
So, why type more when you can type less?
It's purely laziness and ignorance. You should always use the right types for indices, and unless you have further information that restricts the range of possible indices, size_t
is the right type.
Of course if the dimension was read from a single-byte field in a file, then you know it's in the range 0-255, and int
would be a perfectly reasonable index type. Likewise, int
would be okay if you're looping a fixed number of times, like 0 to 99. But there's still another reason not to use int
: if you use i%2
in your loop body to treat even/odd indices differently, i%2
is a lot more expensive when i
is signed than when i
is unsigned...
Using int
to index an array is legacy, but still widely adopted. int
is just a generic number type and does not correspond to the addressing capabilities of the platform. In case it happens to be shorter or longer than that, you may encounter strange results when trying to index a very large array that goes beyond.
On modern platforms, off_t
, ptrdiff_t
and size_t
guarantee much more portability.
Another advantage of these types is that they give context to someone who reads the code. When you see the above types you know that the code will do array subscripting or pointer arithmetic, not just any calculation.
So, if you want to write bullet-proof, portable and context-sensible code, you can do it at the expense of a few keystrokes.
GCC even supports a typeof
extension which relieves you from typing the same typename all over the place:
typeof(arraySize) i;
for (i = 0; i < arraySize; i++) {
...
}
Then, if you change the type of arraySize
, the type of i
changes automatically.
It really depends on the coder. Some coders prefer type perfectionism, so they'll use whatever type they're comparing against. For example, if they're iterating through a C string, you might see:
size_t sz = strlen("hello");
for (size_t i = 0; i < sz; i++) {
...
}
While if they're just doing something 10 times, you'll probably still see int
:
for (int i = 0; i < 10; i++) {
...
}
Consider the following simple example:
int max = some_user_input; // or some_calculation_result
for(unsigned int i = 0; i < max; ++i)
do_something;
If max
happens to be a negative value, say -1, the -1
will be regarded as UINT_MAX
(when two integers with the sam rank but different sign-ness are compared, the signed one will be treated as an unsigned one). On the other hand, the following code would not have this issue:
int max = some_user_input;
for(int i = 0; i < max; ++i)
do_something;
Give a negative max
input, the loop will be safely skipped.