Are signed/unsigned mismatches necessarily bad?
Here is my program:
int main(int argc, char *argv[]) {
unsigned int i;
for (i = 1; i < argc; i++) { // signed/unsigned mismatch here
}
}
argc
is signed, i
is not. Is this a problem?
"signed/unsigned mismatches" can be bad. In your question, you are asking about comparisons. When comparing two values of the same base type, but one signed and one unsigned, the signed value is converted to unsigned. So,
int i = -1;
unsigned int j = 10;
if (i < j)
printf("1\n");
else
printf("2\n");
prints 2, not 1. This is because in i < j
, i
is converted to an unsigned int
. (unsigned int)-1
is equal to UINT_MAX
, a very large number. The condition thus evaluates to false, and you get to the else
clause.
For your particular example, argc
is guaranteed to be non-negative, so you don't have to worry about the "mismatch".
It is not a real problem in your particular case, but the compiler can't know that argc will always have values that will not cause any problems.
Its not bad. I'd fix compiler warnings concerning signed/unsigned mismatch because bad things can happen even if they are unlikely or impossible. When you do have to fix a bug because of signed/unsigned mismatch the compiler is basically saying "I told you so". Don't ignore the warning its there for a reason.
It is only indirectly a problem.
Bad things can happen if you use signed integers for bitwise operations such as &
, |
, <<
and >>
.
Completely different bad things can happen if you use unsigned integers for arithmetic (underflow, infinite loops when testing if a number is >= 0
etc.)
Because of this, some compilers and static checking tools will issue warnings when you mix signed and unsigned integers in either type of operation (arithmetic or bit manipulation.)
Although it can be safe to mix them in simple cases like your example, if you do that it means you cannot use those static checking tools (or must disable those warnings) which may mean other bugs go undetected.
Sometimes you have no choice, e.g. when doing arithmetic on values of type size_t
in memory management code.
In your example I would stick to int
, just because it is simpler to have fewer types, and the int
is going to be in there anyway as it is the type of the first argument to main()
.