I’m a little fuzzy on how variable access between .cpp files works. For instance:
main.cpp
int main()
{
int a = i;
return 0;
}
main2.cpp
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)
main2.cpp
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?
main2.cpp
namespace
{
int i;
}
To sum up:
- Can variables be accessed between .cpp files? (aside from extern keyword)
- How does the static keyword on a global variable affect things?
- How do anonymous namespaces affect things differently?
In your first example,
main2.cppdefines a global variablei, which could have been accessed bymain.cppif anexterndeclaration ofihad appeared in that file. (Normally that extern declaration would come from a header file.) You got a compiler error becauseihad never been declared inmain.cpp, which means the compiler assumes there is no such variable.In your second example,
main2.cppdefines a file scope variablei. File scope variables are distinct from globals, even if they happen to have the same name. If you had had an extern declaration ofiinmain.cppin the second example, both files would have compiled successfully, but then you would have gotten a link error because no global variableiwas defined.If you renamed
main2.cppfrom the second example tomain3.cpp, added an extern declaration ofitomain.cpp, compiled all three and linked them all together, that would succeed; main.cpp and main2.cpp would share one variable namedi, andmain3.cppwould have its own entirely separate variable also namedi.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 thenamespace { ... }block to get this effect.) You can’t do that any other way.