Expanding it out by hand:
foreach(int *v, values)
printf("value: %d\n", *v);
becomes
for (int keep = 1, count = 0, size = sizeof values / sizeof *(values); keep && count != size; keep = !keep, count++)
for (int *v = (values) + count; keep; keep = !keep)
printf("value: %d\n", *v);
The outer loop iterates over the array. The inner loop creates an item to which the current array element is assigned (int *v
), and then the statements in the body of the foreach
loop use that item (i.e., the body of the foreach
loop becomes the body of the inner for
loop). The keep
flag makes sure that the inner loop only executes 1 time. Trace through the logic by hand for a few iterations and you should see the pattern.
Effectively, it's treating v
as an iterator over the array values
. As such, it's fairly clever; you can use this macro to iterate over an array of any type, such as
double dval[N];
...
foreach( double *d, dval )
do_something_with( *d );
But...
As written, this code does have some pitfalls. It won't work with dynamically-allocated arrays:
int *vals = malloc( sizeof *vals * N );
...
foreach( int *v, vals ) // bzzzzt!
printf( "%d\n", *v );
since sizeof vals
only gives you the size of the pointer variable, not the size of the allocated buffer. Similarly, it won't work on any array passed as a function parameter.
Be very suspicious of any macro that attempts to extend language syntax; it's always a hack, and almost always has a fatal weakness or two.