The extern keyword in C and C++ extends the visibility of variables and functions across multiple source files.

In the case of functions, the extern keyword is used implicitly. But with variables, you have to use the keyword explicitly.

I believe a simple code example can explain things better in some cases than a wall of text. So I'll quickly setup a simple C++ program for demonstration.

If you have GCC installed on your system you may follow along. Otherwise, I'll include outputs from each code snippet with them for you to read through.

extern with Functions

In the example, I have two C++ files named main.cpp and math.cpp and a header file named math.h. Code for the math.h file is as follows:

int sum(int a, int b);

As you can see, the header file contains the declaration for a simple function called sum that takes two integers as parameters. The code for the math.cpp file is as follows:

int sum(int a, int b) {
    return a + b;
}

This file contains the definition for the previously declared sum function and it returns the sum of the given parameters as an integer.

Finally, the code for the main.cpp file is as follows:

#include <iostream>
#include "math.h"

int main () {
    std::cout << sum(10, 8) << std::endl;
}

This file includes the math.h header file containing the declaration for the sum function. Then inside the main function, the std::cout << sum(10, 8) << std::endl; statement calls the sum functions by passing 10 and 8 as the two parameters and prints out whatever the returned value is.

Now if you try to compile this program you'll see it compiles without any problem and upon executing the resultant binary file, you'll see following output in the console:

18

This works (even though the definition of the sum function is in a separate file than main.cpp) because all the functions in C/C++ are declared as extern. This means they can be invoked from any source file in the whole program.

You can declare the function as extern int sum(int a, int b) instead but this will only cause redundancy.

extern with Variables

Although the extern keyword is applied implicitly to all the functions in a C/C++ program, the variables behave a bit differently.

Before I dive into the usage of extern with variables, I would like to clarify the difference between declaring a variable and defining it.

Declaring a variable simply declares the existence of the variable to the program. It tells the compiler that a variable of a certain type exists somewhere in the code. You declare a float variable as follows:

float pi;

At this point, the variable doesn't have any memory allocated to it. The compiler only knows that a float variable named pi exists somewhere in the code.

Defining the variable, on the other hand, means declaring the existence of the variable, as well as allocating the necessary memory for it. You define a variable as follows:

float pi = 3.1416;

You can declare a variable as many times as you want, but you can define a variable only once. This is because you can not allocate memory to the same variable multiple times.

Now, I'll modify the math.h header file created in the previous section to contain the declaration for the pi variable as follows:

extern float pi;
int sum(int a, int b);

As you can see, the variable has been declared as an extern in the header file, which means this should be accessible anywhere in the program. Next, I'll update the main.cpp file as follows:

#include <iostream>
#include "math.h"

int main () {
    std::cout << pi << std::endl;
    std::cout << sum(10, 8) << std::endl;
}

I've added a new std::cout statement to print out the value of the pi variable. If you try to compile this program at this point, the compilation process will fail.

Starting build...
C:\mingw64\bin\g++.exe -fdiagnostics-color=always -g C:\Users\shovi\repos\cpp-playground\extern\*.cpp -o C:\Users\shovi\repos\cpp-playground\extern\extern.exe
c:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\shovi\AppData\Local\Temp\ccFIWkmh.o:main.cpp:(.rdata$.refptr.pi[.refptr.pi]+0x0): undefined reference to `pi'
collect2.exe: error: ld returned 1 exit status

Build finished with error(s).

This happens because, declaring the variable has let the compiler know that this variable exists somewhere in the program – but in reality it doesn't. It has no memory allocation at all.

To get out of this problem, I'll define the pi variable inside the math.cpp file as follows:

float pi = 3.1416;

int sum(int a, int b) {
    return a + b;
}

The compilation process finishes without any issues, and if I execute the resultant binary, I'll see the following output in my console:

3.1416
18

Since the pi variable has been declared as an extern and has been defined within the math.cpp file, the main.cpp file is able to access the value of pi without any problem at all.

You can define the variable anywhere in the program but I chose the math.cpp file for definition to prove the point that this extern variable indeed is available to all the other source files as well.

Conclusion

Even though it's not used that often, the extern keyword in C/C++ is undoubtedly one of the most important concept to understand. I hope you've understood how the keyword works at a basic level from this short article.

As you continue to use the keyword in your programs, you'll definitely come across problems and situations that are outside the scope of this article. Feel free to reach out to me in Twitter and LinkedIn if you think I can be of help. Otherwise, Stack Overflow is always there to help.

Also, if you're native Bengali speaker, checkout freeCodeCamp's Bengali Publication and YouTube Channel. Till the next one, stay safe and keep learning.