Skip to content

Commit ad50ea7

Browse files
fixup! fixup! fixup! fixup! fixup! fixup! fixup! Fix #1473: warn when fclose() is used as a while loop condition
1 parent d1d6247 commit ad50ea7

1 file changed

Lines changed: 40 additions & 0 deletions

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# fcloseInLoopCondition
2+
3+
**Message**: fclose() used as loop condition may skip loop body or double-close file handle.<br/>
4+
**Category**: Resource Management<br/>
5+
**Severity**: Warning<br/>
6+
**Language**: C and C++
7+
8+
## Description
9+
10+
Using `fclose()` as a loop condition leads to two unwanted outcomes:
11+
12+
- On **success**, the condition is false and the loop body never executes. The intent was likely to process the file inside the loop, but it is already closed.
13+
- On **failure**, the condition is true and the loop body executes but `fclose()` is called again on the already-closed file handle on the next iteration, which is undefined behaviour.
14+
15+
This pattern is almost always a misunderstanding of what `fclose()` returns, or confusion with a function that reads/processes data incrementally (like `fgets` or `fread`). Unlike those functions, `fclose()` is a one-shot teardown operation and has no meaningful retry or loop-until-done semantic.
16+
17+
## How to fix
18+
19+
Call `fclose()` outside the loop condition. If you need to check whether the close succeeded, store the return value and test it separately.
20+
21+
Before:
22+
```c
23+
FILE *fp = fopen("data.txt", "r");
24+
while (fclose(fp)) {
25+
/* process file */
26+
}
27+
```
28+
29+
After:
30+
```c
31+
FILE *fp = fopen("data.txt", "r");
32+
/* process file */
33+
if (fclose(fp) != 0) {
34+
/* handle close error */
35+
}
36+
```
37+
38+
## Related checkers
39+
40+
- `useClosedFile` - for using a file handle that has already been closed

0 commit comments

Comments
 (0)