I'm a little fuzzy on how variable access between .cpp files works. For instance:
int main()
{
int a = i;
return 0;
}
int i;
This generates a compiler error on main.cpp, telling me there is no in i in existence. What difference then, does the "static" keyword do in this context? (I tried Googling for it, but most of the "static keyword" info pages talk about classes & functions)
static int i;
Is it the same? Does it prevent extern int i
being used to access i
elsewhere? How does the use of anonymous namespaces differ in how variables are handled?
namespace
{
int i;
}
To sum up:
In your first example, main2.cpp
defines a global variable i
, which could have been accessed by main.cpp
if an extern
declaration of i
had appeared in that file. (Normally that extern declaration would come from a header file.) You got a compiler error because i
had never been declared in main.cpp
, which means the compiler assumes there is no such variable.
In your second example, main2.cpp
defines a file scope variable i
. File scope variables are distinct from globals, even if they happen to have the same name. If you had had an extern declaration of i
in main.cpp
in the second example, both files would have compiled successfully, but then you would have gotten a link error because no global variable i
was defined.
If you renamed main2.cpp
from the second example to main3.cpp
, added an extern declaration of i
to main.cpp
, compiled all three and linked them all together, that would succeed; main.cpp and main2.cpp would share one variable named i
, and main3.cpp
would have its own entirely separate variable also named i
.
This stuff is called linkage . Namespaces are almost entirely unrelated to linkage. However, the anonymous namespace is special. Defining a variable in an anonymous namespace is for all practical purposes the same as defining it with static
-- it makes it a file scope variable. (If I remember correctly, there is a difference, but it only matters if you are doing complicated things with exported templates, and as exported templates are so little used that they're talking about deleting the feature from the C++ standard, you don't have to worry about it.)
The value of the anonymous namespace is that you can put a class definition inside it, and that makes all of the class's methods be file-local. (Only the class { ... }
block has to be inside the namespace { ... }
block to get this effect.) You can't do that any other way.
All global variables have some kind of linkage . extern
linkage is required to name the same variable in different contexts between different files.
extern
is the default. If you actually use extern
in a variable declaration, it's treated as a reference to another file. Omit any linkage specifier to actually create the variable; this must happen in only one file.
extern int i; // i exists somewhere in some .cpp file.
int i; // ah! this is the file it exists in.
// (Although nothing special about that.)
static
applied to a global (at namespace scope) makes it local to the file. You get the same effect from a private namespace, so static
outside function or class scope is deprecated. Many still use it though.
The exception to the rule of static
meaning file-local is in classes and inline
functions. Class static
members should more properly be called extern
since the semantics are identical. It's ugly and confusing, but I guess Bjarne just wanted to eliminate extern
as a keyword.
Inline functions can have the same definition among multiple .cpp
files, so when one creates a static
variable, the variable definition is shared as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.