c – Compiling with header files – Education Career Blog

Compiling the file main.c with:

gcc main1.c -o final

gives me:

/tmp/cc1cwhAP.o: In function `main':
main1.c:(.text+0xb): undefined reference to `hi'
main1.c:(.text+0x15): undefined reference to `hi'
collect2: ld returned 1 exit status


#include <stdio.h>
#include "incl.h"

int main(void)
 hi = 1;
 printf("hi = %d",hi);


extern int hi;

What am I doing wrong? (Please be verbose with your answers)

Removing the extern keyword solves the issue, but I want to be able to use the hi variable in other source files.


You’ve told the compiler that there exist a variable called hi, but you have not actually defined it.

There’s two ways to solve this:

  1. Drop the extern keyword in the declaration in the header file. This is BAD!
  2. Declare the variable in a source file. This can be either the main1.c or another source file, that you link into the program. This is the good way.


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.”


When you declare a variable extern, it means to the compiler that it will be defined in some c modules and should be found during linking.

You still need to define a global int hi in one .c file.
Any .c file including your header file will be able to use it.


Put the actual int hi in one of your source codes. And then extern will reference to that.

Leave a Comment