"smart" indexing

C

Capstar

Hi NG,

I am developing a piece of software, which contains basicly one loop,
which consinsts of 2 parts. Thos two parts are again basicly the same,
but they deiffer in some variables. So I changed the variables from foo0
and foo1 to foo[2], so I can index them. This way I can run through the
loop two times more, but switch the index between 0 and 1.
This is pretty easy. I did it this way:

int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee that idx=!idx always result
in a 1 or a 0? And if I would want the compiler to loop unroll this,
would that work? Or does that only work for a for loop which has a clear
end statement in stead of a break?

Thanks in advance,
Mark
 
R

Russell Hanneken

Capstar said:
int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee that idx=!idx always result
in a 1 or a 0?

Yes, it does (section 6.5.3.3, paragraph 5).
And if I would want the compiler to loop unroll this,
would that work? Or does that only work for a for loop which has a clear
end statement in stead of a break?

That I don't know. :-\
 
I

Ivan Vecerina

Hi,
....
| This is pretty easy. I did it this way:
|
| int idx;
| for(idx=0;;idx=!idx)
| {
| do_something_with(foo[idx]);
| if(somestatement) break;
| }
|
| my question is:
| Does the standard guarantee that idx=!idx always result in a 1 or a 0?

Yes.
Alternatively, you could write:
idx = 1-idx; // not really better
or:
idx = (idx+1)%2; // could apply to any range ( %3, %4, etc... )

| And if I would want the compiler to loop unroll this,
| would that work? Or does that only work for a for loop which has a clear
| end statement in stead of a break?

As all optimizations, loop unrolling is very implementation-specific.
You'll have to try and check the generated code to be sure.
Or not worry about it, until you need to optimize the performance
of your code.

radix omnia malorum prematurae optimisatia est
-- Donald Knuth


Cheers,
Ivan
 
L

LibraryUser

Capstar said:
.... snip ...

int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee that idx=!idx always
result in a 1 or a 0?

Yes. However you can have a much simpler and clearer loop with:

for (idx = 0; idx < 2; idx++) {
do_something_with(foo[idx]);
}

(Note that the blank shortage ended several years ago)
 
P

pete

Capstar said:
Hi NG,

I am developing a piece of software, which contains basicly one loop,
which consinsts of 2 parts. Thos two parts are again basicly the same,
but they deiffer in some variables.
So I changed the variables from foo0
and foo1 to foo[2], so I can index them.
This way I can run through the
loop two times more, but switch the index between 0 and 1.
This is pretty easy. I did it this way:

int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee
that idx=!idx always result in a 1 or a 0?

Yes.
And if I would want the compiler to loop unroll this,
would that work?
Or does that only work for a for loop which has a clear
end statement in stead of a break?

I don't know.
I'd write that loop, this way:

idx = 1;
do {
idx = !idx;
do_something_with(foo[idx]);
} while (!somestatement);
 
C

Capstar

LibraryUser said:
Capstar wrote:

... snip ...
int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee that idx=!idx always
result in a 1 or a 0?


Yes. However you can have a much simpler and clearer loop with:

for (idx = 0; idx < 2; idx++) {
do_something_with(foo[idx]);
}

I agree that this is a much simpler and clearer loop, but it doesn't
meet my requerements, I don't want the loop to end after 2 iterations.
It should continue until a certain condition is met. So the values for
idx shoudl be 0,1,0,1,0,1,0,1,....

(Note that the blank shortage ended several years ago)

What is "the blank shortage"?

Mark
 
C

Capstar

pete said:
Capstar said:
Hi NG,

I am developing a piece of software, which contains basicly one loop,
which consinsts of 2 parts. Thos two parts are again basicly the same,
but they deiffer in some variables.
So I changed the variables from foo0
and foo1 to foo[2], so I can index them.
This way I can run through the
loop two times more, but switch the index between 0 and 1.
This is pretty easy. I did it this way:

int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee
that idx=!idx always result in a 1 or a 0?


Yes.

And if I would want the compiler to loop unroll this,
would that work?
Or does that only work for a for loop which has a clear
end statement in stead of a break?


I don't know.
I'd write that loop, this way:

idx = 1;
do {
idx = !idx;
do_something_with(foo[idx]);
} while (!somestatement);

Yes, I appologise for my example being to much simplified perhaps. The
if(somestatement) break; is somewhat longer. It is actually if
(somestatement) { wait_event_interruptible_timeout(...); break;);

I could probably also do the wait_blabla after the while-loop, but again
that would give me some trouble.

Thanks for your input anyway,
Mark
 
P

pete

Capstar said:
int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}
And if I would want the compiler to loop unroll this,
would that work?

According to my understanding of what "unrolling" is,
I think that you have to know the minimum number of times
that the loop will execute, in order to unroll it just that much.
I don't see any indication that that number is higher than one.
 
R

Robert Stankowic

Capstar said:
LibraryUser said:
Capstar wrote:

... snip ...
[....]

What is "the blank shortage"?

Once upon a time the suppliers of blanks were unable to deliver enough
blanks, so every C programmer had to write things like

for(i=0,j=5;i<234&&somecondition||someothercondition;i+=somevalue)
{
yabbadabba...
}
(note there was an underliner - shortage as well)
But that is over, Now we can write:

for(i = 0, j = 5; i < 234 && some_condition || some_other_condition; i +=
some_value)
{
yabbadabba...
}
which is slightly better readable :)
no attack intended :)
Robert
 
G

Glen Herrmannsfeldt

Capstar said:
LibraryUser said:
Capstar wrote:

... snip ...
int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}
my question is: Does the standard guarantee that idx=!idx always
result in a 1 or a 0?
Yes. However you can have a much simpler and clearer loop with:

for (idx = 0; idx < 2; idx++) {
do_something_with(foo[idx]);
}

I agree that this is a much simpler and clearer loop, but it doesn't
meet my requerements, I don't want the loop to end after 2 iterations.
It should continue until a certain condition is met. So the values for
idx shoudl be 0,1,0,1,0,1,0,1,....

In that case, I would make two loops. One to do the 0,1 part, and another
loop outside that one, so that the compiler would easily see the loop to
unroll.

As in a post I answered yesterday, too bad the preprocessor can't do this.
In PL/I you can do:

%DO idx=0 TO 1;
do_something_with(foo[idx]);
%END;

and the preprocessor will expand it for you.

You could write your own preprocessor. It isn't all that uncommon a
solution to these problems.

-- glen
 
J

Joe Wright

pete said:
int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}
And if I would want the compiler to loop unroll this,
would that work?

According to my understanding of what "unrolling" is,
I think that you have to know the minimum number of times
that the loop will execute, in order to unroll it just that much.
I don't see any indication that that number is higher than one.

I see two. Rather I see any number of iterations with idx == 0, idx ==
1, idx == 0, ad nauseum until (somestatement) is 'true'. Note 'idx=!idx'
is an assignment 'idx = !idx' which is a toggle, 0 to 1 to 0, etc.
 
A

Arthur J. O'Dwyer

Capstar said:
It should continue until a certain condition is met. So the values for
idx should be 0,1,0,1,0,1,0,1,....

In that case, I would make two loops. One to do the 0,1 part, and
another loop outside that one, so that the compiler would easily see
the loop to unroll.

As in a post I answered yesterday, too bad the preprocessor can't do
this. In PL/I you can do:

%DO idx=0 TO 1;
do_something_with(foo[idx]);
%END;

and the preprocessor will expand it for you.

You could write your own preprocessor. It isn't all that uncommon a
solution to these problems.

Well, in this case the C preprocessor will be fine. I've done
similar things before:


#define do_something(FOO) \
{ \
... /* lines of stuff ending with backslashes */ \
}

....
do_something(0);
do_something(1);


Simple, right?
(Searchers for more complicated stuff, or stuff involving loops
from 0 to 15126 instead of 0 to 1, might be advised to write a
program that could generate the tricky bits of the program you
want. Basically what Glen said, but you really don't need a
whole preprocessor if you want to do only one thing!)

-Arthur
 
K

Kevin D. Quitt

pete said:
idx = 1;
do {
idx = !idx;
do_something_with(foo[idx]);
} while (!somestatement);

Yes, I appologise for my example being to much simplified perhaps. The
if(somestatement) break; is somewhat longer. It is actually if
(somestatement) { wait_event_interruptible_timeout(...); break;);

So make it this:

idx = 1;
for (;;) // or while (1)
{
idx = !idx;
do_something_with(foo[idx]);
if (somestatement)
break;
}


Six of one, half a gross of the other.
 
L

LibraryUser

Capstar said:
LibraryUser said:
Capstar wrote:

... snip ...
int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee that idx=!idx
always result in a 1 or a 0?


Yes. However you can have a much simpler and clearer loop with:

for (idx = 0; idx < 2; idx++) {
do_something_with(foo[idx]);
}

I agree that this is a much simpler and clearer loop, but it
doesn't meet my requerements, I don't want the loop to end
after 2 iterations. It should continue until a certain condition
is met. So the values for idx shoudl be 0,1,0,1,0,1,0,1,....

Then let me suggest:

idx = 0;
do {
dosomethingwith(foo[idx]);
idx = !idx;
} while (somestatement);
What is "the blank shortage"?

The thing that entices some programmers to write:

for(idx=0;;idx=!idx)

in place of:

for (idx = 0; ; idx = !idx)
 
P

pete

LibraryUser said:
LibraryUser said:
Capstar wrote:

... snip ...

int idx;
for(idx=0;;idx=!idx)
{
do_something_with(foo[idx]);
if(somestatement) break;
}

my question is: Does the standard guarantee that idx=!idx
always result in a 1 or a 0?


Yes. However you can have a much simpler and clearer loop with:

for (idx = 0; idx < 2; idx++) {
do_something_with(foo[idx]);
}

I agree that this is a much simpler and clearer loop, but it
doesn't meet my requerements, I don't want the loop to end
after 2 iterations. It should continue until a certain condition
is met. So the values for idx shoudl be 0,1,0,1,0,1,0,1,....

Then let me suggest:

idx = 0;
do {
dosomethingwith(foo[idx]);
idx = !idx;
} while (somestatement);

That leaves idx with a different value after the loop concludes,
than it had in the dosomethingwith() call, unlike the original code.
OP didn't specify if it was important,
but I wouldn't take it upon myself to assume that it wasn't.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,125
Latest member
VinayKumar Nevatia_
Top