Originally Posted by
KIBO
For instance when you pass an array to a function and to be correct you better pass a size_t as the size too.
Code:
void func(OBJ results[3], size_t n) {
for (int i = 0; i < n; i++) {
if (results[i] != 0)
results[i].SetVal(i);
}
}
}
Then if you loop through the array with an int you get the warning that you're mixing unsigned and signed types but if you change it to size_t and the SetVal expects an int then you get the warning there.
How do you guys solve this?
It really depends. Your code as written needs to do more error checking that it does, or have a documented set of preconditions (eg n <= 3) that is enforced by the caller.
However, I'd do it something like this;
Code:
void func(OBJ results[3], size_t n)
{
for (size_t i = 0; i < n && i < 3U; i++) /* enforce range check */
{
if (results[i] != 0)
results[i].SetVal((int)i); /* we know i < 3 so the conversion is safe */
}
}
There is also no mandatory punishment for using additional variables, and that's one way to avoid having to do a conversion. For example;
Code:
void func(OBJ results[3], size_t n)
{
size_t i;
int i_as_int;
for (i = 0, i_as_int = 0; i < n && i < 3U; i++, i_as_int++)
{
if (results[i] != 0)
results[i].SetVal(i_as_int);
}
}
}
The only catch is that it's not possible to define variables of two distinct types within the for() construct, which is the reason I've moved the variable definitions before the loop. There is potentially a (very slight) overhead in this but, if the relationship between i and i_as_int is well defined (eg above: they're equal value, although different types) modern compilers will often optimise out one of the variables anyway.
In C++, one other way is to overload the SetVal() member function so it accepts either int or a size_t. Of course, that forces one of the SetVal() functions to do a conversion, but at least it's localised.