How does the following example usage of extern specifer behave.
We have a global variable int x both in files one.c and two.c
We want to use these in three.c so have declared this variable in three.c as
extern int x;
What would happen when we compile and link these files?
My answer is: compilation of all these files should succeed, however the linker should flag an error at linking, due to multiple declarations of x.
Would there be any difference in behavior in C++ ?
Is these any way to refer to int x (in three.c) simultaneously from both files, in C and C++.
In C++, I guess we can use namespaces to acheive this. Right?
By default, global variables have external linkage, which means that they can be used by other source files (or “translation units”). If you instead declare your global variables with the
statickeyword, they will have internal linkage, meaning they will not be usable by other source files.For variables with external linkage, you can’t have multiple variables with the same name, or the linker will complain. You can have two variables with the same name, though, as long as at least one has internal linkage, and of course you can’t reference both of them in the same source file.
An
externdeclaration is just saying to the compiler “here is the name of some variable with external linkage defined in another translation unit,” allowing you to refer to that variable.C++ is exactly the same, except for the addition of namespaces. If global variables are put inside a namespace, then they can have the same name without linker errors, provided they are in different namespaces. Of course, all references to those variables then have to either refer to the full name
namespace::var_name, or use ausingdeclaration to establish a local namespace context.C++ also has anonymous namespaces, which are entirely equivalent to using the
statickeyword for global variables in C: all variables and functions declared inside an anonymous namespace have internal linkage.So, to answer your original question, you are right — compilation would succeed, but linking would fail, due to multiple definitions of the variable
xwith external linkage (specifically, from the translation unitsone.candtwo.c).From
three.c, there is no way to refer simultaneously to both variablesx. You’ll need to renamexin one or both modules, or switch to C++ and put at least onexinside a namespace.