How does GCC interpret ferror definition?

119 views Asked by At

I'm working with some embedded C code for an LCD display in which one of the files includes stdio.h and defines fputc, fgetc, and ferror. fputc calls the LCD driver code to print a character to the screen, but the other two don't actually do anything interesting.

Whenever I try to compile the project I get the following error:

src/ST7735.c:1578:5: error: expected identifier or '(' before 'int' 1578 | int ferror(FILE *f){

src/ST7735.c:1578:5: error: expected ')' before '(' token 1578 | int ferror(FILE *f){

The error goes away if I rename ferror to anything else. The other two functions don't create any issues. I also found that if I do rename the function but call ferror elsewhere in the code, the project still compiles, when I'd expect linking to fail without a definition for ferror anywhere else in the project.

I'm using the arm-none-eabi toolchain with the -nostdlib flag, but the project was originally created using Keil. I'm not sure if that is part of the explanation. I searched Google for any relevant information but couldn't find anything. Is there something special about ferror in GCC?

1

There are 1 answers

0
Eric Postpischil On BEST ANSWER

… one of the files includes stdio.h and defines fputc, fgetc, and ferror.

This seems like you are trying to implement those standard library functions, as in the way a C implementation must implement those functions for its users.

An implementor of standard library functions is responsible for providing both the header, <stdio.h>, and the implementations of the functions and for ensuring they work together. Including somebody else’s <stdio.h> and writing your own definitions is not generally a good approach to this. Often somebody else’s implementation of <stdio.h> contains customizations for that implementation that are not appropriate for yours. It is typically better to start by writing your own <stdio.h> that simply declares functions as they are described in the C standard.

Failing that, there might be no need to include <stdio.h> in the source file where you are defining fputc, fgetc, and ferror. Simply remove that header and define the functions.

If you do not wish to do that, then adding #undef ferror after #include <stdio.h> might resolve the immediate problem you are having. However, it might not resolve the whole problem, because, if source files that are using your routines include this same <stdio.h>, they will get the ferror macro defined in <stdio.h> and will not call the ferror routine you define. To resolve that, you will need to provide a different <stdio.h>.