Aviv Cohn
Aviv Cohn

Reputation: 17183

Why do I need to declare a global as `extern` if I want to use it?

I understand that file-scope variables in C are by default extern - even if this isn't specified explicitly (as explained in this answer to Global variables in C are static or not?).

However, I also know that if a.h declared extern int x = 10;, and b.c wants to access x, it needs to declare it as extern.

Why is it so? Why not just access x without any additional extern stuff? What is the technical explanation of this mechanism?

Upvotes: 1

Views: 113

Answers (3)

Because the variable is external to the file; it is defined in another file, and you just tell that file that it exists, but it won't find it there. Then it's the job of the linker to solve that.

Example:

// a.c
int x = 7;

a.c has the variable defined

// a.h
extern int x;

a.h has knowledge that the variable exists, but it doesn't know where. Any file that includes a.h will gain that knowledge

// b.c
#include "a.h"

b.c, because it has included a.h, now has knowledge that the variable x exists, but doesn't know where.

The linker will resolve those different usages of the same variable x. They better be the same, or there will be problems.

You could lie to a.h, and write a float instead of int, and only the linker may notice that, because the compiler literally has no knowledge about a.c (well, a.c should include a.h, so it will notice, but you could lie to it if you don't include it)

In the whole project there must be one and only one non-extern definition of each variable. 0 or 2 or more, and the linker will report an error.

Upvotes: 1

Weather Vane
Weather Vane

Reputation: 34585

The header file a.h should not contain

extern int x = 10;

but just

extern int x;

Then the file a.c should define

int x = 10;

and when file b.c wants to use x it should simply

#include "a.h"

and the compiler, when compiling b.c will know that x is defined somewhere else, and the linker will find the reference and fix it up.


From the added link edit: if the definition is in a compilation unit which is not seen by the compiler then the variable does not magically become available: you need to declare it as extern where the compiler can see, so it knows that it will be available. It serves somewhat the same purpose as a function prototype: it's a delaration, not a definition.

Upvotes: 0

Paul Ogilvie
Paul Ogilvie

Reputation: 25286

Storage for a global variable is only allocated once. For example, in main.c:

int gMyCounter;

In any other module (C-file) where you want to use or acess this variable, you must tell the compiler about its existence and its type. You do that with the extern keyword, for example in mymodule.c:

extern int gMyCounter;

During link time, the linker sees that mymodule.o needs variable gMyCounter and searches for it in the other .o files and libraries. It finds it in main.o.

Upvotes: 1

Related Questions