1

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.

Will Bickford
  • 5,381
  • 2
  • 30
  • 45
user1086516
  • 887
  • 3
  • 9
  • 21

4 Answers4

3

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);
}
Mysticial
  • 464,885
  • 45
  • 335
  • 332
1
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; ) { ... }
wildplasser
  • 43,142
  • 8
  • 66
  • 109
  • As with my solution, this doesn't do the same thing as the questioner's code in the case where `count == 1`. – Steve Jessop Dec 09 '11 at 10:40
  • I guess you're right. for the strange case of the OP wanting to loop once for cnt=1, a ternary should be added. (I don't expect him to want that) I'll UPDATE. – wildplasser Dec 09 '11 at 10:55
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
}
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
0

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.

Community
  • 1
  • 1
Steve Jessop
  • 273,490
  • 39
  • 460
  • 699