tags:

views:

379

answers:

3

Is it better to cast the iterator condition right operand from size_t to int, or iterate potentially past the maximum value of int? Is the answer implementation specific?

int a;
for (size_t i = 0; i < vect.size(); i++)
{
    if (some_func((int)i))
    {
        a = (int)i;
    }
}

int a;
for (int i = 0; i < (int)vect.size(); i++)
{
    if (some_func(i))
    {
        a = i;
    }
}
+3  A: 

I'd just leave it as a size_t, since there's not a good reason not to do so. What do you mean by "or iterate potentially up to the maximum value of type_t"? You're only iterating up to the value of vect.size().

mipadi
+1  A: 

For most compilers, it won't make any difference. On 32 bit systems, it's obvious, but even on 64 bit systems, both variables will probably be stored in a 64-bit register and pushed on the stack as a 64-bit value.

If the compiler stores int values as 32 bit values on the stack, the first function should be more efficient in terms of CPU-cycles.

But the difference is negligible (although the second function "looks" cleaner)

Philippe Leybaert
Thanks, yes I was thinking the 2nd looks cleaner since there's less casting. Agreed?
nbolton
+5  A: 

I almost always use the first variation, because I find that about 80% of the time, I discover that some_func should probably also take a size_t.

If in fact some_func takes a signed int, you need to be aware of what happens when vect gets bigger than INT_MAX. If the solution isn't obvious in your situation (it usually isn't), you can at least replace some_func((int)i) with some_func(numeric_cast<int>(i)) (see Boost.org for one implementation of numeric_cast). This has the virtue of throwing an exception when vect grows bigger than you've planned on, rather than silently wrapping around to negative values.

Mike Elkins
I like the idea of an exception being thrown in this case, since it eliminates any really weird behaviour... Then again, it'd be a massive amount of hassle, considering it's probably never going to go over `INT_MAX`.
nbolton
@Nick: Why do you think that adding a include and using a different cast (and a proper one, FTM -- C-style casts are never proper) is too much hassle.
sbi
A function should "do what you want". A function that "does what you want until some undocumented limit is crossed and then does something else" is what is commonly termed a "landmine". Leaving landmines in your code is always a bad idea for anything other than a homework problem.
Mike Elkins