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?
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 definingfputc
,fgetc
, andferror
. 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 theferror
macro defined in<stdio.h>
and will not call theferror
routine you define. To resolve that, you will need to provide a different<stdio.h>
.