C ++ access to variables from .CPP files

I don't understand a bit how variable access works between .cpp files. 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 what I'm missing. What is the difference then, does this make a β€œstatic” keyword in this context? (I tried Google for this, but most of the "static keyword" info pages talk about classes and functions)

main2.cpp

 static int i; 

It is the same? Does this prevent the use of extern int i to access i elsewhere? How does using anonymous namespaces differ in how variables are handled?

main2.cpp

 namespace { int i; } 

Summarizing:

  • Are variable variables between .cpp files? (except for the keyword extern)
  • How does a static keyword in a global variable affect things?
  • How do anonymous namespaces affect things differently?
+4
source share
3 answers

In the first example, main2.cpp defines the global variable i , which could be accessed by main.cpp if the extern i declaration appeared in this file. (Usually, the extern declaration comes from the header file.) You have encountered a compiler error since i never declared in main.cpp , which means that the compiler assumes that there is no such variable.

In your second example, main2.cpp defines the scope variable of the i file. File scope variables are different from global, even if they have the same name. If in the second example you had an extern i declaration in main.cpp , both files would be compiled successfully, but then you would get a link error because the global variable i was not defined.

If you renamed main2.cpp from the second example to main3.cpp , added the extern declaration from i to main.cpp , compiled all three and linked everything together, which would be successful; main.cpp and main2.cpp will use the same variable named i , and main3.cpp will have its own completely separate variable, also called i .

This material is called bond. Namespaces are almost completely unrelated to binding. However, an anonymous namespace is special. Defining a variable in an anonymous namespace for all practical purposes is the same as defining it with static β€” making it a variable in the file area. (If I remember correctly, there is a difference, but it only matters if you do complex things with exported templates, and since the exported templates are used so little that they say about removing a function from the C ++ standard, I have to worry about it.)

The value of the anonymous namespace is that you can put a class definition in it, and that makes all the class methods local. (To get this effect, there should only be a class { ... } block inside the namespace { ... } block.) You cannot do this in any other way.

+2
source

All global variables have some kind of connection. extern requires linking the same variable in different contexts between different files.

extern is the default value. If you actually use extern in a variable declaration, it is treated as a link to another file. Omit any binding specifier to actually create the variable; this should 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 applies to the global (in the namespace area) makes it local in the file. You get the same effect from the private namespace, so the static outer function or scope of the class is deprecated. Many still use it, though.

An exception to the static rule is file-local in classes and inline . The static class should be more correctly called extern , since the semantics are identical. It is ugly and confusing, but I think Bjarne just wanted to exclude extern as a keyword.

Built-in functions can have the same definition among several .cpp files, so when you create a static variable, the variable definition is also shared.

+1
source
  • yes for example you can use static class variables
  • it makes the variable local and constant for the compilation unit
  • An anonymous namespace prevents character collisions. it's as if you were creating the same namespace manually
0
source

All Articles