Linkage, files and header

Hi guys. I'm wondering how does the complier link files together? Is it linked once you run all files in 1 single program or do I need to specify somewhere?

And when do I need a header? If the files are linked when complied, why do I still need a header? I mean the complier can cross reference by itself? Like for example if you use "main.cpp" and "test.cpp".

Got pretty confused by files and headers though. I understand what is external, internal and no linkage stuff.

Thanks!

EDIT: Thought I would be more explicit. Say I have this namespace created in test.cpp
1
2
3
4
5
6
//test.h
namespace test_ns
{
    int x;
    int y;
}

1
2
3
4
5
6
//test.cpp
namespace test_ns
{
    int x = 10;
    int y = 11;
}

And then I have this main function...
1
2
3
4
5
6
7
8
9
#include <iostream>
#include "test.h" //if let's say there's no namespaces, do I require it?
                          //like if I only have external variables in another .cpp file

int main()
{
    std::cout << test_ns::x << " " << test_ns::y << std::endl;
    return 0;
}
Last edited on
I'm wondering how does the complier link files together? Is it linked once you run all files in 1 single program or do I need to specify somewhere?

Normally all source files (.cpp) in your project is compiled and then linked together to produce the executable file. There is something called dynamic linking which is quite common with libraries which means the library will be loaded and linked when you run the program. This has a few advantages, it reduces the size of your program and it allows the user to upgrade the library without recompiling your program, but this also means the library has to be installed in order to run your program, and you have less control over which version of the library is being used.

If you use an IDE much of this is hidden from you but there are many compiler settings you can use to control how compilation and linking is done.

And when do I need a header? If the files are linked when complied, why do I still need a header? I mean the complier can cross reference by itself? Like for example if you use "main.cpp" and "test.cpp".

A header is never strictly needed, it just makes it easier to write your program. #include works as an automatic copy-paste. It simply takes the content of the file and includes it in the file. You would get the exact same result if you replaced the #include with the text in that header file.

If you want to call a function or create an instance of a class the compiler need to know that there is such a function and class, otherwise it will give an error.

1
2
3
4
5
int main()
{
	A a; // This gives an error because the compiler doesn't know what A is.
	foo(a); // This gives an error because the compiler doesn't know what foo is.
}

To make it compile we can declare the function and define the class before we use them.

1
2
3
4
5
6
7
8
class A {};
void foo(A);

int main()
{
	A a;
	foo(a);
}

This will compile and you could do it like this, but if A and foo will be used elsewhere you would have to add the class definition and the function declaration to all files that use them and that can be error prone. If you made a change to the class you would have to remember to make the exact same change everwhere and it could be a lot of work and easy to make a mistake.

A much better way is to put these things into a header file. Then we only need to include the file when we want to use them and we only have to modify one file if we want to make a change.

A.h
1
2
class A {};
void foo(A);

main.cpp
1
2
3
4
5
6
7
#include "A.h"

int main()
{
	A a;
	foo(a);
}

Note that this has nothing to do with linking. It's just used to make the program compile.

EDIT: Thought I would be more explicit. Say I have this namespace created in test.cpp

By convention we don't include source files (.cpp). You would have a problem if you tried to include test.cpp from more than one source file because z, test_ns::x and test_ns::y would be defined more than once which is not allowed. You probably be able to compile the files but when everything is linked together it would notice that the variables has been defined more than once and give you a linker error.
Last edited on
Is it linked once you run all files in 1 single program or do I need to specify somewhere?

Not sure what you mean here. When you build a program each .cpp and .c file is compiled to an object file (.obj or .o or ...) and then linked together (with the appropriate libraries) to create the final binary (.exe, .dll, .so, ...)

why do I still need a header?

The compiler can't cross reference the functions in your source files (during the compile phase.) You need to make sure that a delaration for your functions has been seen before you use it. This is done by including headers which declare the function which have been implemented (defined) in other .cpp files.

But you could do this by cutting and pasting the declaration into the top of all the .cpp files that use it. But this would not be a smart move, for reasons of maintainability. If you changed a function in one .cpp file you would then have to alter the declaration at the top of every other .cpp file (lots of them, in some cases) rather than one header.

But when you source is compiled, the resultant .obj/.o files have the information in them which is required to link them together. Headers are not used at this point (during the link phase.)

Got pretty confused by files and headers though.

See:

Headers and Includes: Why and How
http://www.cplusplus.com/articles/Gw6AC542/

Organizing Code Files in C and C++
http://www.gamedev.net/page/resources/_/technical/general-programming/organizing-code-files-in-c-and-c-r1798

Andy
Thanks for your replies. I will check out the links! But as for this case, why doesn't file1.cpp require #include "file2.h" and why the program doesn't need header for file2?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// file1.cpp
#include <iostream>
using namespace std;
void other(); //some function unrelated to my queries
void another();
int x = 10;
int y;

int main()
{
    other();
    another();
    return 0;
}


1
2
3
4
5
6
7
8
9
// file 2.cpp
#include <iostream>
using namespace std;
extern int x;

void another()
{
cout << "another(): " << x << ", " << y << endl;
}
Last edited on
Thanks for your replies.

Hmmm... How carefully did you read them??

I will check out the links!

I kind of expected you to do a bit of follow up yourself before asking for further information here.

why doesn't file1.cpp require #include "file2.h" ...

Both Peter87 and I said you don't actually need to use a header file; you can write the declarations of the functions and variables that are defined (implemented) in other files at the top of your source file. The compiler just needs a declaration of the function or variable before it's used.

(The compiler does need to know the function or variable has external linkage, of course. But you said you understood those concepts in your original post. And I can see you're using the extern keyword in your code.)

Header files are used because thay make it easier to work with multiple files (real projects usually have a lot more than 3 or 4 files.)

Incidentally, your example is broken. It would have been better here if you had posted working code: y is not visible in file2.cpp, and other() isn't defined (you could have stubbed it?).

Andy
Last edited on
Originally, I don't get the part why the example could simply include a "void another()".

Sorry, my bad. I thought using global functions would require a either a header or an extern (it's optional, didn't notice it initially in the book). I was confused at that void another() part.

Thanks!
Last edited on
Topic archived. No new replies allowed.