Question

This is the subject code:

externfile.cpp

int i = 10;

mainfile.cpp

#include <iostream>

using namespace std;

extern int i;
int main(int param)
{
    cout << i << '\n';
    int i = 0;
    cout << i << '\n';
    cout << ::i << '\n';
}

When compiling this program (using Visual Studio 2008), it works fine and the output will be:

10
0
10

which is not surprising for me, this is a matter of scopes.

But what makes me confused is: How could mainfile.cpp file get the value of i from another .cpp file (externfile.cpp in our case)? is it only because they reside in the same directory? or the same solution?

And in a better way: How are source files "merged" while compiling a project (with VS2008, if I should specify)? in what "order" are they placed? and how are they scoped?

Était-ce utile?

La solution

A "normal" VC++ project1 instruct VC++ to compile each source file by itself to an "object file" (or object module), where the compiler leaves "placeholders" for symbols that aren't resolved yet (like external variables or functions that are declared but not defined).

Then, all the object files are tied together by the linker, which ties them together to produce the final executable. During this passage, the "placeholders" are replaced by the actual address of the code/data they refer to that is defined in the various object files. If some needed definition is not found you get an undefined reference error, if some symbol is found more than once you get a multiple definition error2.

Fore more information about the classical model for linking, have a look at this article by Raymond Chen (and, if you are interested, to the whole series).


  1. Surely there's room for more flexibility, here I'm just describing what's the usual situation in VC++.
  2. This is a consequence of the C++ "one definition rule"; still, there are some exceptions to this, in particular inline functions and template instantiations; in those cases, the linker just takes whatever it prefers (which shouldn't be a problem, since multiple definitions of such objects must be the same).

Autres conseils

Your IDE VS2008 passes your source files to the compiler. The compiler builds your source files to object files, and then passes those files to a linker, the linker links these files as well as your includes.

The linker will then spit out a binary representation of all those files, whether a dll, lib, or exe.

This is a very basic summary of what happens, there are more process that go on.

If you were doing this by hand there would be 4 steps to running a C or C++ program

1 - preprocess, mostly deals with C macros, #define etc.

2 - compile, the files are converted to object code with a table of external symbols so these can be resolved later

3 - link, resolve the external references, report any errors if it can't find them

4 - run the code.

All of this is automated by the IDE, VS2008. It makes these steps occur as needed, if a file hasn't changed it isn't recompiled, if no link is needed it isn't done. In .Net there are more steps needed to make assemblies etc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top