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.
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).