I have a really simple C program:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
FILE* f = fopen("file.txt", "r");
char c;
while (fscanf(f, "%c", &c) == 1) {
printf("char: %c\n", c);
}
}
which works perfectly fine, reading one character at a time from the file. But if I change the condition on the while loop to while (fscanf(f, "%c", &c) != 0)
, the program appears to get stuck in an infinite loop of printing some whitespace character. I looked at the assembly, and they're identical except for a single instruction:
== 1 version
...
40068a: be 5d 07 40 00 mov $0x40075d,%esi
40068f: 48 89 c7 mov %rax,%rdi
400692: b8 00 00 00 00 mov $0x0,%eax
400697: e8 94 fe ff ff callq 400530 <__isoc99_fscanf@plt>
40069c: 83 f8 01 cmp $0x1,%eax
40069f: 74 c9 je 40066a <main+0x24>
4006a1: b8 00 00 00 00 mov $0x0,%eax
4006a6: c9 leaveq
4006a7: c3 retq
4006a8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
4006af: 00
!= 0 version
40068a: be 5d 07 40 00 mov $0x40075d,%esi
40068f: 48 89 c7 mov %rax,%rdi
400692: b8 00 00 00 00 mov $0x0,%eax
400697: e8 94 fe ff ff callq 400530 <__isoc99_fscanf@plt>
40069c: 85 c0 test %eax,%eax
40069e: 75 ca jne 40066a <main+0x24>
4006a0: b8 00 00 00 00 mov $0x0,%eax
4006a5: c9 leaveq
4006a6: c3 retq
4006a7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
And the only difference is a test
versus cmp
. This is as far as my knowledge of reading assembly goes, and I don't see a difference. So what causes the difference in behavior?
fscanf
might also returnEOF
(which could be negative) – IronManfscanf()
? What happens in case of==1
and what in the case of!=0
at all the possible return values you can expect. – 12431234123412341234123EOF
must be negative, per 7.21 Input/output <stdio.h> paragraph 3: "...EOF
which expands to an integer constant expression, with type int and a negative value ..." – Andrew Henle