Scope of a variable outside main in C
Consider the code:
#include <stdio.h>
int x;
int main (void)
{ }
The value of x
is 0
inside main
. But why is that? 开发者_Go百科I have not declared it to be static
. Or is it assumed static
as it is outside a function?
If the above is true, how does it make it different from an extern
?
It's neither static
nor extern
. It's a variable visible for the compilation unit it's in, and additionally will be visible from all compilation units that declare x
to be an extern
variable.
Why am I saying it's neither static
nor extern
?
If it was extern
, then, there must be a different compilation unit with x
declaration on it. Clearly this is your only compilation unit.
If it was static
then, no extern
reference would be allowed to x
variable defined in this compilation unit. We know that we could easily declare an extern
variable to this x
declared here.
Why is 0
assigned to x
? Because, in C, all global variables initialize to 0
. It says so in 6.7.8 (10) of the C99 standard.
When we say that variables of "static storage duration" are initialized to 0 implicitly, we don't mean that you need to put the "static" keyword in front of them.
"static storage duration" merely is a specific kind of storage duration for objects that says that their storage lasts for the complete duration of the program. This kind of storage duration is used for variables declared at file scope (like your variable) and local static variables.
6.2.2/5: "If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external."
That's linkage, though, not scope. Your declaration of x
would have file scope either way. static
and extern
don't affect scope. It's initialized to 0 because x
has static storage duration (see 6.2.4/3 and /5).
In general you also have to be aware of 6.2.2./4:
For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, 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.
So declaring with extern
is not quite the same as declaring with no storage-class specifier. In your example there is no prior declaration, though.
It's not static. It's global. You can declare it extern
in a different compilation unit, but space will be allocated for it in this one. Globals are always initialized to 0 if they aren't given initializers, by the way.
Your compiler initialized the value of x to be 0.
It's a global variable which is visible from within main()
x is a global variable, it has space allocated for it when the program starts and is initialized to 0 (generally, however you should have an explicit initializer).
The 'static' keyword has two different meanings.
1)
static int x; int main() { }
This limits the scope of x to the single file. Although it is still a global variable, the linker will not be able to connect references to x from other files.
2)
int main() { static int x; }
This effectively turns x into a global variable. Although the scope is still within the main function, space is allocated for it globally, and it's value will be retained between calls to main().
This feels like a homework question but I'll bite anyhow.
To use the x you have defined here in a class or function from another file, you would use
extern int x;
above your usage of the x variable (like in the header) then you can use x just like you would in main(). extern tells the compiler that you are using a variable that is defined/instantiated elsewhere.
If you want it to exist before the main is run, then you use static which is handled prior to main() running. In other words it loads the memory space with variables prior to kicking off any processing (in main.)
As to why it is 0 on startup, that is likely just your compiler giving it a base value. Not all compilers do this, unless I am mistaken, many will just give you whatever was in the memory space allocated to x which could be anything. In other words they give you the memory complete with whatever data (or partial data) was in it beforehand.
精彩评论