I was trying to apply a patch to a suckless program and came across an error where the compiler did not recognize the static variables declared in the header that was used in the application file.
The header file only contains static variables and the application has the appropriate include for said header
snippets:
header file (config.h)
1 2 3 4 5 6 7 8
/* default message */
staticconstchar * message = "Suckless: Software that sucks less.";
/* text color */
staticconstchar * text_color = "#ffffff";
/* text size (must be a valid size) */
staticconstchar * font_name = "6x10";
application file (slock.c)
1 2 3 4 5 6 7 8
int evbase;
int errbase;
};
#include "config.h"
staticvoid
die(constchar *errstr, ...)
error message:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
slock.c: In function ‘writemessage’:
slock.c:100:40: error: ‘font_name’ undeclared (first use in this function)
100 | fontinfo = XLoadQueryFont(dpy, font_name);
| ^~~~~~~~~
slock.c:100:40: note: each undeclared identifier is reported only once for each function it appears in
slock.c:114:18: error: ‘text_color’ undeclared (first use in this function)
114 | text_color, &color, &dummy);
| ^~~~~~~~~~
slock.c:127:22: error: ‘message’ undeclared (first use in this function)
127 | len = strlen(message);
| ^~~~~~~
slock.c: In function ‘main’:
slock.c:416:17: error: ‘message’ undeclared (first use in this function); did you mean ‘usage’?
416 | message = EARGF(usage());
| ^~~~~~~
| usage
make: *** [Makefile:19: slock.o] Error 1
config.h is such a common name, are you sure you're including the one you think you are?
Does the header file have the usual include guards, like
1 2 3 4 5 6 7 8 9 10 11 12 13
#ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED
/* default message */
staticconstchar * message = "Suckless: Software that sucks less.";
/* text color */
staticconstchar * text_color = "#ffffff";
/* text size (must be a valid size) */
staticconstchar * font_name = "6x10";
#endif
If you've mistakenly copy/pasted the include guards from some other file, or otherwise ended up re-using the define from some other file, the compiler will think you've already included config.h and not include it again.
You can run the pre-process step by itself using gcc -E slock.c > slock.txt
It will be a large file, but if you search for "die(const char *errstr, ...)", then immediately before that will be the content of your config.h.