This question is motivated by the following (simplified) example.
Consider the following code:
void f(unsigned int x) { }
int main()
{
int z = 3;
if (z > 0)
for (unsigned int i = 0; i < z; ++i)
f(i);
return 0;
}
Compiling with all warnings enabled, the compiler issues a
warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’
This is clearly not a real problem, since the code explicitly checks that the upper limit in the for loop is positive.
One way to eliminate the warning is to explicitly static_cast
z:
int main()
{
int z = 3;
if (z > 0)
for (unsigned int i = 0; i < static_cast<unsigned int>(z); ++i)
f(i);
return 0;
}
At least in this simplified example, both codes compile to the same assembler, see it on godbolt. Indeed, I would not expect that a cast from an int to unsigned int to result in any instructions, since both types are stored with the same number of bits.
Which leads to the question: when does static_cast
result in no compiled instructions? Is this always the case for a static_cast
between integers having the same size in bits?
When you don't have the cast there, the compiler adds a conversion for you anyway, so it makes sense that they both compile to identical machine code. But when it is implicit, it's likely that you weren't expecting or even aware of that (just search on StackOverflow for the number of cases people try to compare vector.size()
with -1
). So your compiler generates a warning to ask you to confirm that's really what you want.