Skip to content

Fix #958: warn when feof() is used as a while loop condition#8422

Open
francois-berder wants to merge 3 commits intodanmar:mainfrom
francois-berder:pr-958
Open

Fix #958: warn when feof() is used as a while loop condition#8422
francois-berder wants to merge 3 commits intodanmar:mainfrom
francois-berder:pr-958

Conversation

@francois-berder
Copy link
Copy Markdown
Contributor

feof() only returns true after a read has already failed, causing the loop body to execute once more after the last successful read. Read errors also go undetected since feof() does not distinguish them from EOF.

feof() only returns true after a read has already failed, causing
the loop body to execute once more after the last successful read.
Read errors also go undetected since feof() does not distinguish
them from EOF.

Signed-off-by: Francois Berder <fberder@outlook.fr>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 8, 2026

@chrchr-github
Copy link
Copy Markdown
Collaborator

How does the check handle do ... while loops? Should we skip those?
There are obviously other ways to check the return value of feof, e.g. using ==. Another extension would be handling of for loops, but maybe that could be added later. @danmar

Comment on lines +494 to +495
if (!cond)
continue;
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code is redundant. simpleMatch returns false if the token is null

Suggested change
if (!cond)
continue;

{
reportError(tok, Severity::warning,
"wrongfeofUsage",
"Using feof() as a loop condition may cause the last line to be processed twice.\n"
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want that you remove the word "may". Can you somehow check if it is actually processed twice.

if there is no bug we shouldn't warn. example:

   char line[100];
   fgets(line, sizeof(line), f);
   while (!feof(f)) {
        dostuff(line);
        fgets(line, sizeof(line), f);
    }


void testWrongfeofUsage() { // ticket #958
check("void foo() {\n"
" FILE * fp = fopen(\"test.txt\", \"r\");\n"
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass fp as parameter. then the testcase can be 2 lines shorter (no open/close).

@danmar
Copy link
Copy Markdown
Owner

danmar commented Apr 9, 2026

thank you for adding this checker! it's good work. small and simple. just try to make it more precise.
please add a line in the release notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants