Question
I want to understand how the extern keyword is used in C to share variables between source files.
I know that global variables sometimes appear with the extern keyword, but I am not sure what an extern variable actually is. Specifically:
- What does
externmean for a variable? - What does the declaration look like?
- What scope does such a variable have?
- How does sharing a variable across multiple
.cfiles work in practice? - In which file should
externbe used, and where should the variable actually be created?
For example, I am trying to understand the pattern behind code like this:
/* file1.c */
int counter = 0;
/* file2.c */
extern int counter;
How does this work precisely in C?
Short Answer
By the end of this page, you will understand the difference between declaring and defining a global variable in C, what extern means, how scope and linkage affect shared variables, and how to correctly share one variable across multiple source files without causing linker errors.
Concept
In C, extern is mainly used to say:
"This variable exists somewhere else. I want to use it here, but I am not creating storage for it in this file."
That idea is the key to understanding extern.
Declaration vs definition
A global variable can appear in two important ways:
- Definition: actually creates the variable and allocates storage for it.
- Declaration: tells the compiler the variable exists and what its type is.
Example:
int counter = 0; // definition
extern int counter; // declaration
The definition creates one real counter variable in the program. The extern declaration does not create a second variable. It only allows another source file to refer to the existing one.
Why this matters
C programs are often split into multiple .c files. Each source file is compiled separately, so the compiler needs to know the types of names used in that file. If one file wants to use a global variable defined in another file, it needs a declaration. That is what extern is for.
Scope vs linkage
Mental Model
Think of a shared global variable like a company storage locker.
- The definition is the actual locker built in one location.
- An
externdeclaration is a note telling people: "The locker exists in building A; use that one." - If every building creates its own locker with the same name, there is confusion.
- If everyone only has notes but no locker was ever built, nothing can be stored.
So:
- one real locker = one definition
- many references to that locker =
externdeclarations
This is why extern is about referring to existing storage, not creating new storage.
Syntax and Examples
Core syntax
Define a global variable
int counter = 0;
This creates the variable.
Declare a global variable from another file
extern int counter;
This says the variable exists somewhere else.
Basic multi-file example
globals.h
#ifndef GLOBALS_H
#define GLOBALS_H
extern int counter;
#endif
globals.c
#include "globals.h"
int counter = 0;
main.c
{
(, counter);
counter += ;
(, counter);
;
}
Step by Step Execution
Consider these files.
globals.h
#ifndef GLOBALS_H
#define GLOBALS_H
extern int counter;
#endif
globals.c
#include "globals.h"
int counter = 10;
main.c
#include <stdio.h>
#include "globals.h"
int main(void) {
printf("%d\n", counter);
counter++;
printf("%d\n", counter);
return 0;
}
Step-by-step
1. is included in
Real World Use Cases
When shared globals are used
Although global variables should be used carefully, they do appear in real C programs.
Configuration flags
extern int debug_enabled;
Used by multiple source files to enable extra logging.
Program state counters
extern unsigned long request_count;
Useful in small tools or embedded systems to count events.
Hardware register mappings in embedded C
A shared global may represent device state or a system-wide handle used across modules.
Shared error/status values in legacy code
Older codebases sometimes expose shared status variables accessible from several files.
Better alternatives in many cases
In modern C code, developers often prefer:
- passing values through function parameters
- keeping state inside a
struct - limiting visibility with
static - exposing accessor functions instead of raw globals
These approaches reduce coupling and make code easier to test.
Real Codebase Usage
In real projects, extern is usually part of a small, repeatable pattern.
Common pattern: declaration in header, definition in source
app_state.h
#ifndef APP_STATE_H
#define APP_STATE_H
extern int app_mode;
#endif
app_state.c
#include "app_state.h"
int app_mode = 1;
This is the standard way to expose one global object to multiple files.
Common pattern: hide most globals with static
Developers often avoid exposing variables unless necessary.
static int internal_cache_size = 128;
This variable can only be used inside its own .c file. That is often safer.
Access through functions
Common Mistakes
1. Defining the variable in a header
This is a very common mistake.
Broken code
/* globals.h */
int counter = 0;
If several .c files include this header, each file gets its own definition, causing linker errors.
Correct version
/* globals.h */
extern int counter;
/* globals.c */
int counter = 0;
2. Using extern but never defining the variable
Broken code
/* globals.h */
extern int counter;
If no source file contains:
int counter;
then the linker cannot find the real variable.
3. Confusing scope with linkage
Beginners may think changes scope everywhere automatically. It does not.
Comparisons
extern declaration vs definition
| Form | Example | Creates storage? | Typical use |
|---|---|---|---|
| Definition | int counter = 0; | Yes | Create the variable once |
Declaration with extern | extern int counter; | No | Refer to variable defined elsewhere |
External linkage vs internal linkage
| Keyword/form | Example | Visible from other files? | Notes |
|---|---|---|---|
| Default global definition | int counter = 0; |
Cheat Sheet
Quick rules
externusually means: this variable is defined somewhere else- Use
externfor declarations, not for creating the variable - Define the variable once in one
.cfile - Put the
externdeclaration in a header if multiple files need it - Include that header wherever the variable is used
Common pattern
/* globals.h */
extern int counter;
/* globals.c */
int counter = 0;
/* main.c */
#include "globals.h"
counter++;
Remember
int counter = 0;→ definitionextern int counter;→ declarationstatic int counter = 0;→ private to that source file
Linkage summary
FAQ
What does extern mean in C?
It means the variable or function is declared here but defined somewhere else, usually in another source file.
Does extern create a variable?
No. A declaration like extern int x; does not create storage for x. It only tells the compiler that x exists.
Where should I put extern declarations?
Usually in a header file, so every source file that needs the variable can include the same declaration.
Where should I define the actual global variable?
In exactly one .c file.
What is the difference between extern int x; and int x;?
extern int x; is a declaration only. int x; at file scope is typically a definition.
Can I use extern inside a function?
Yes. It declares that the name refers to an external variable, but this is less common than putting the declaration in a header.
Can extern access a variable from another file?
Mini Project
Description
Build a small multi-file C program that keeps track of how many tasks have been completed. The counter should be shared across source files using extern. This demonstrates the correct pattern for declaring a shared global in a header and defining it in exactly one .c file.
Goal
Create a program where multiple source files read and update the same global counter variable.
Requirements
- Create a header file that declares a shared variable with
extern. - Define the shared variable in exactly one source file.
- Use one source file to increase the counter.
- Use another source file to print the counter.
- Confirm that both files access the same variable.
Keep learning
Related questions
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.
Definition vs Declaration in C and C++: What’s the Difference?
Learn the difference between declarations and definitions in C and C++ with simple examples, common mistakes, and practical usage.
Difference Between #include <...> and #include "..." in C and C++
Learn the difference between #include with angle brackets and quotes in C and C++, including search paths, examples, and common mistakes.