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?
CodePudding user response:
… one of the files includes
stdio.h
and definesfputc
,fgetc
, andferror
.
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>
.