while loop with variable definition in C
I'm currently trying to loop over a collection retrieved by an API in C.
The API offers a function getNext() that returns a reference to the next element in the collection, or NULL if the end has been reached.
Now i wanted to declare a variable in a while expression and loop until NULL:
// create collection from API
Collection collection = create();
if (collection == NULL) {
return -1
}
while (const Element *e = getNext(collection) != NULL) {
// print data from e
}
When compiling, 'error: unexpected expression' pops up. Why does that statement not work in C? How can I loop over the collection when all I have is a function getNext() that returns either an element or NULL?
I also tried the following, but the same error occured:
while ((const Element *e = getNext(collection)) != NULL) {
// print data from e
}
Solution 1:
It is not possible because while()
expects an expression and it is not possible to place a declaration in the expression (though it is possible to introduce a new type with expression!).
The best you can get is:
const Element *e;
while ((e = getNext(collection)) != NULL) {
// print data from e
}
It is however possible to achieve the desired functionlity with a for
loop.
for (const Element *e; (e = getNext(collection)) != NULL; ) {
// print data from e
}
Solution 2:
First of all, in contrast to a for
statement, you cannot declare a new variable in a while
statement. Therefore, the following line is wrong:
while (const Element *e = getNext(collection) != NULL) {
You could fix this by writing the following:
const Element *e;
while ( e = getNext(collection) != NULL ) {
A more compact way of writing this is the following:
for ( const Element *e; e = getNext(collection) != NULL ; ) {
The second version has the advantage that the scope of the variable e
is limited to the for
loop.
However, the lines mentioned above are also wrong, for the following reason:
The !=
operator has higher precedence than =
. So the line
while ( e = getNext(collection) != NULL) {
is equivalent to:
while ( e = ( getNext(collection) != NULL ) ) {
This is not want you want. You should write the following instead:
while ( ( e = getNext(collection) ) != NULL ) {