Question

I have this code that works fine for regular signed integers that I am trying to write an equivalent version that will work with size_t (as in that as of now start and count are ints and i need them to be size_t) :

int count,start;
for (start = (count-2)/2; start >=0; start--)
{
     someFunction( x, start, count); // x is to illustrate function has other parameters
}

I feel like this code is straight forward enough for a really simple solution but I am drawing a blank.

Was it helpful?

Solution

You could rewrite it like this:

start = count/2;
while (start > 0){
    start--;
    someFunction( x, start, count);
}

Otherwise, the only other option I can think of is to do some non-standard compliant casting between signed and unsigned... or to do something with ~(size_t)0...

Here are some non-standard compliant alternatives:

for (start = (count-2)/2; (ssize_t)start >= 0; start--)
{
     someFunction( x, start, count);
}

for (start = (count-2)/2; start != ~(size_t)0; start--)
{
     someFunction( x, start, count);
}

OTHER TIPS

size_t cnt, start;
for (start = cnt/2; start-- > 0; ) { ... }
  • if cnt=0 : start will start at zero, the loop code will never execute; after the loop, start will be (size_t)-1
  • if cnt=1 : the same
  • if cnt >=2 : the loop code will execute at least once; on the first iteration, start will be (cnt/2)-1; on the last iteration start will be 0; after the loop start will be (size_t)-1

EDIT if the OP really wants to loop once for cnt=1, a ternary is necessary:

for (start = (cnt==1) ? 1 : cnt/2; start-- > 0; ) { ... }

What about just using a value off by one?

size_t start_plus_one;
for (start_plus_one = (count-2)/2+1; start_plus_one >=1; start_plus_one--)
{
     someFunction( x, start_plus_one-1, count); // x is to illustrate function has other parameters
}

You can fix the end condition from your original code. -1/2 is guaranteed to be 0 in C99, which makes the loop body execute once, so you might have to treat count == 1 specially if that's still the required behavior once the types are unsigned.

size_t count = something;
if (count > 1) {
    for (size_t start = (count-2)/2; start != SIZE_MAX; --start) {
        someFunction(x, start, count);
    }
}

This works because we know that the initial value of start cannot possibly be SIZE_MAX, because there is no value of size_t that when divided by 2 yields SIZE_MAX.

For more general loops, that might need to start at SIZE_MAX and go all the way down to 0 inclusive, clearly we cannot perform the exit check before the loop body, because we want the loop body to execute once for every value of size_t, so there is no value on which we can exit. To allow for that case:

size_t count = SIZE_MAX, start = SIZE_MAX;
do {
    someFunction(x, start, count);
} while (start-- != 0);

In all cases, SIZE_MAX can be replaced with -1, which is more generic in that it converts to the max value of every unsigned type, but leads to confused questions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top