简体   繁体   中英

C++ accessing variables from .CPP files

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.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.

  • yes, for example you can use static class variables
  • it makes variable local and persistent to compilation unit
  • anonymous namespace prevents collision between symbols. it is as if you create uniquely named namespace manually

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM