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

main1.c:

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

int main(void)
{
 hi = 1;
 printf("hi = %d",hi);
 return(0);
}

incl.h:

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