socrates
socrates

Reputation: 347

Double parenthesis around expression in While loop

I was attempting to read a file as such:

char c;
while ((c = fgetc(fp) != EOF)) { ... }

And was not stepping into the loop. Why doesn't this code work?

I realized the error was failing to place the wrapping parenthesis before the not equals comparison to EOF, as such:

char c;
while ((c = fgetc(fp)) != EOF) { ... }

However, I don't understand why the first conditional doesn't work. I tested it with printf("%d", c = fgetc(fp) != EOF), and that returns 1. So the issue must be something to do with the conditional being wrapped inside of (...) parenthesis, which would seem to make it be evaluating to while ( (1) ).

I bet I am misunderstanding RE: the operator association order, but do not know for certain the root of the error here.

Upvotes: 3

Views: 680

Answers (1)

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

The condition expression depends on the precedence of operations.

In fact in this while loop

while ((c = fgetc(fp) != EOF)) { ... } 

you may remove a pair of external parentheses like

while ( c = fgetc(fp) != EOF ) { ... } 

because they do not change the semantic of the condition.

Now according to the operator precedence this loop looks like

while ( c = ( fgetc(fp) != EOF ) ) { ... } 

The expression in the inner parentheses ( fgetc(fp) != EOF ) is evaluated either to integer 0 or 1 as a logical expression.

So as result you will get either

while ( c = 1 ) { ... }

if the expression ( fgetc(fp) != EOF ) evaluates to the logical true or

while ( c = 0 ) { ... }

if the expression evaluates to the logical false.

Pay attention to that the variable c shall be declared as having the type int because it is the return type of the function fgetc that can return the value EOF.

int c;
while ( ( c = fgetc(fp) ) != EOF ) { ... }

Otherwise you will compare an object of the type char and an object of the type int that is defined as the macro EOF.

However in general the type char can behave as the type unsigned char (depending on a compiler option or by default) and in this case due to the integer promotion an object of the type char (that stores a non-negative value) will never be equal to EOF that is defined usually like -1. (or like some other negative value).

Upvotes: 2

Related Questions