Let's forget about header files for a bit (after all their contents are inserted inside source files during compilation and they only exist during pre-processing). They're only an easy way to use the same code in several source files (think copy/paste). So, in the interest of efficiency, that duplicated code should do nothing; or we risk doing something more than once.
int x; /* puts aside a memory area with space for an int and call it x */
extern int x; /* tell the compiler that x exists and it is an int */
Which of the above does less? That's the one to put in a header file. But as we've told the compiler x
exists, we need to actually define it somewhere. The best place to define it is in a source file.
As header files don't do anything, they're pretty much safe to insert into lots of source files.
Now, back to header files. They're usually linked to a specific source file (through their names: foobar.h is linked to foobar.c). This is a good method to identify where declarations in the header file are defined.
/* foobar.h */
extern int x;
void myfoo(int);
After seeing this header file, I'd expect foobar.c
to contain the definition of x
and myfoo
.
/* foobar.c */
int x; /* global x. BAD BAD BAD */
void myfoo(int alpha) { x = !x; return x ? alpha : 0; }
Why globals are bad?
quote from http://c2.com/cgi/wiki?GlobalVariablesAreBad
Really Bad Reasons to Use Global Variables
- "I'm a slow typist. Globals save me keystrokes."
- "I don't want to pass it around all the time."