A certain C file had a new header added. Rebuilding the project produced an error in that C file.

Bash
src/xxxx.c: In function ‘foo’:
src/xxxx.c:27:1: error: parameter ‘some_pp’ is initialized
src/xxxx.c:27:1: warning: initialization from incompatible pointer type [enabled by default]

Line 27 is the declaration of a file-scope global variable some_pp, and it checks out fine. function foo is something this file needs: a declaration from the referenced header.

Everything before line 27 is just macro definitions or header declarations—there’s simply no way for it to be wrong.

More importantly, this file has been compiled many times before, so the earlier part can basically be considered problem-free. The only change was adding a header file (headername.h). Inspecting the header revealed the following code:

C
#ifndef __HEADERMANE_H__
#define __HEADERMANE_H__
// bla bla ...
int foo(int offset,const char *str)
#endif // __HEADERMANE_H__
foo is a function declaration, but the trailing semicolon was forgotten. Appending a ; at the end of line 4 in headername.h fixes the problem.

GCC interpreted the subsequent contents of xxxx.c as part of function foo, then found they didn’t match and finally aborted with an error.

This reminds us that compilers only report errors when they really can’t continue parsing, and the location they point to is often after the actual mistake. We need to search backward from the reported position to find the real source of the error—sometimes tracing back many lines, or even across more than one file.