Can we use a variable in a file using extern which is defined as both static as well as global in the base file?
You can't extern
-redefine a static
variable, though you can extern
-redeclare it.
WRONG:
//filescope
static int x = 42;
extern int x = 43; //WRONG
CORRECT:
//filescope
static int x = 42;
extern int x; //redeclares the previous STATIC x (no linkage)
extern
doesn't declare a linkage-having identifier with external linkage: it (re)declares the identifier with its previous linkage (external or internal) unless there was no such previous declaration or the declaration didn't have linkage (non-static locals have no linkage).
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.
I wouldn't try to push this behavior with complex overshadowing, though, because neither gcc and clang like extern-redeclarations of an inner static and if you have intervening auto variables between a global static and an innermost extern
redeclaration, then the innermost identifier will have conflicting linkage, which results in undefined behavior as per 6.2.2p7 (Thanks to Eric Postpischil for pointing this out).
accepted by gcc and clang:
#include <stdio.h>
static int x = 42;
extern int x;
int main()
{
extern int x;
printf("x=%d\n", x); //42
}
accepted by clang only (technically UB due to conflicting linkage)
#include <stdio.h>
static int x = 42;
extern int x;
int main()
{
int x = 1000;
printf("x=%d\n", x); //1000
{
extern int x; //conflicting (external) linkage
//=> undefined behavior due to http://port70.net/~nsz/c/c11/n1570.html#6.2.2p7
printf("x=%d\n", x); //42 on clang; compile time error on gcc
}
}
perhaps curiously unaccepted by either:
#include <stdio.h>
static int x = 42;
extern int x;
int main()
{
static int x = 1000;
extern int x;
printf("x=%d\n", x); //1000?
}
int x = 1000;
inside main
, the standard is not ambiguous, and both GCC and Clang are conforming: at the inner extern int x;
, only the x
of int x = 1000;
is visible, since it hides the prior declarations, and so it is the one referred to by 6.2.2 4. The prior declaration, int x = 1000;
has no linkage, so the new x
has external linkage. Then x
has been declared with both internal linkage (by the first static int x = 42
and external (by this new one), for which the standard says the behavior is not defined, so both GCC and Clang conform, since anything does. –
Irving © 2022 - 2024 — McMap. All rights reserved.