According to C standard:
In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.
In my example we have three separate declarations with each identifier having a different linkage.So why doesn't this work?
static int a; //a_Internal
int main(void) {
int a; //a_Local
{
extern int a; //a_External
}
return 0;
}
Error:
In function 'main': Line 9: error: variable previously declared 'static' redeclared 'extern'
Why does compiler insist that I'm redeclaring instead of trying to access external object in another file?
Valid C++ example for reference:
static void f();
static int i = 0; // #1
void g() {
extern void f(); // internal linkage
int i; // #2 i has no linkage
{
extern void f(); // internal linkage
extern int i; // #3 external linkage
}
}
Both Clang and VC seem to be okay with my C example; only some versions of GCC (not all) produce the aforementioned error.
Internal linkage refers to everything only in scope of a translation unit. External linkage refers to things that exist beyond a particular translation unit. In other words, accessible through the whole program, which is the combination of all translation units (or object files).
Explanation: External Linkage-> means global, non-static variables and functions. Internal Linkage-> means static variables and functions with file scope. None Linkage-> means Local variables.
adjective Referring to an inheritance pattern for 2 genes on the same chromosome in which the frequency for crossing over is the same as it is for 2 genes on different chromosomes.
The two different types of linkage are: Complete linkage. Incomplete linkage.
§6.2.2, 7 says:
If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.
So, your program has undefined behaviour.
§6.2.2, 4 says that
extern int a; //a_External
has external linkage because the prior declaration visible in the scope int a; //a_Local
has no linkage. But
static int a; //a_Internal
declares a
with internal linkage. Hence, it's undefined per §6.2.2, 7.
The compiler is giving this error because inside the a_External
scope, a_Internal
is still accessible, thus you are redeclaring a_Internal
from static
to extern
in a_External
because of the name collision of a
. This problem can be solved by using different variable names, for example:
static int a1; //a_Internal
int main(void) {
int a2; //a_Local
{
extern int a3; //a_External
}
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With