Quote:Original post by Defend
6. (Sight between files.)
When I use multiple .cpp files, the IDE is automatically making sure the compiler knows it has to include them all. Okay. And including a header is the same as pasting all the text from that header into the file that is including it. Okay. But can someone please give me some clarification on what "sight" there is between different .cpp files? I'm guessing/assuming that something declared at file scope (outside all the {} braces) is a global and can be seen from anywhere in any of the .cpp files. Correct?
Disregard your IDE: it's a useful tool that insulates you from what's really happening, and you question asks about what's really hapening.
A .cpp file is fed to a program called a compiler, which under Microsoft's Visusal Studio is a program named CL.EXE. The compiler will first preprocess the file by pulling in all #included files and performaing textual replacements, and then parsing and interpreting the C++ code. Finally, it emits another file containing chunks of machine code wrapped in various instructions on how those chunks fit together. These files are called object files and under Microsoft's Visual Studio appear as .OBJ files. Each source file and object file are standalone and know nothing about other source and object files.
The next phase in program construction is to read in all object files and link libraries (which are collections of object files) through a program called a linker, which in Microsoft's Visual Studio is called LINK.EXE. This program reads the labels and instructions wrapping the chunks of machine code in each object file and combines them into a final executable program image. Some object files have a tag saying "I need symbol X", and other have a tag declaiming "I provide symbol X." The linker matches the needs and the provides.
So, you ask in a dazed and exhausted manner, what's with these needs and provides? Isn't that like each .cpp file seeing what's in another? Well, kinda, only it's not the .cpp files, it's the linker after reading the object files.
In C++, names declared at namespace level by default have external linkage. Say what? Well, namespace level is essentially not a member of a class (or struct) and not declared in automatic storage (that is, inside a function). In C, that would be like a "global" variable, only such a beast does not exist in C++ -- the closest equivalent to a global variable in C is a namespace-level variable in the :: namespace in C++. So, to the linker, unless otherwise explcitly specified, any name that appears at namespace level is visible to the linker, so potentially accessible from any .cpp file (assuming it is declared correctly in the code visible in that .cpp file).
Capiche?
Now, if you have two identical names visible to the linker, but each applies to a different object (saym two structs, or an int and a float), you will run into trouble. The ODF (one definition rule) may cause a link failure. Or, linkage may succeed but you will have a difficult to track down runtime error. This is why header files are used: by including identical chunks of source code you up the chances of making sure the names presented to the linker are for identical objects. This is also why doing a full rebuild in Visual Studio can make some bizarre and hard-to-solve runtime problems just up and disappear.
Quote:
So it isn't possible to declare a variable that is only visible to the file it was declared in without actually putting it inside some braces. Right?
Wrong. You can give any namespace level variable internal linkage using the static keyword in its declaration.