I read over a few articles about this, and am taking a few introductory courses to C++ concurrently. All of the courses I am taking and these articles just don't help me understand how to implement the extern
and static extern
storage class. I don't feel comfortable moving on until I really have a grasp on this, even though what I am seeing from other programmers is that they do not use these storage classes, but use inheritance from a header file and local static
storage class to use a static variable in a function. Both of those instances I can do. I figured out how to use the static
storage class both within the same source file and also by inheriting the static variable from an inherited source file.
I keep getting linker and / or compiler errors.
I am using Visual Studio 2015 Community Edition with C++11, and have CodeDroid in Android with C++98.
Will someone please teach me how to use the extern
and static extern
storage classes without linker and compiler errors?
For example, say I had one.cpp and two.cpp. Say I have an int main()
function in one.cpp. Say I want to demonstrate outputting the value of an extern
int in the main()
function. And, say I have a void function called extFuncExample()
declared and defined in one.cpp, and also want to output its value there.
A course I am taking has extern
and static extern
as two different storage classes. So, if you would be so kind as to break this down to me, so I can output these values without compiler and linker errors.
Thank you so much!
one.cpp
#include <iostream>
#include "Two.cpp"
int main()
{
extern int global_int;
std::cout << "global_int = " << global_int << '\n';
return 0;
}
two.cpp
#include <iostream>
int global_int = 100;
This, I found works. I was including #include "two.cpp"
in one.cpp and also using the extern
storage class which was causing the issues. Removed #include "two.cpp"
and it worked!
In C and C++ there is a difference between a (forwards) declaration and a definition of symbols. extern
is used to forwards declare the existence of a symbol which is external to the translation unit, that is: to 'import' symbol from "somewhere" and "make it visible" to the code being compiled. At link time the references to external
symbols are resolved.
Effectively extern
is a way to instruct the compiler/toolchain that it should not expect to find the symbol definition among the code being compiled, but instead should look in the libraries being linked against to find it. The linker will not bother to do so for symbols that aren't declared extern
.
Apart from that, there is a somewhat common mistake that people make with extern
: to use it to declare a global variable and also define it inside a header. For example:
// some header.h
extern int my_global = 40; // = 40 makes this wrong.
Then they proceed to include it multiple times in different translation units (source files):
// file1.c{pp}
#include "header.h"
// file2.c{pp}
#include "header.h"
At this point you have introduced multiple definitions for the same symbol in your program because #include
simply copies the contents of the header verbatim into the context at which the #include
is performed. The compiler will still compile the code, but the linker will refuse to link it because of the multiple definition error.