Headers... a question I could never figure out

OK, this is saddening to have to write but this question is getting to me.

You are not supposed to define functions in headers right? It's because of potential for multiple definitions of the function which is illegal. But a header guard makes sure that the stuff in the header never gets defined twice, so why not? And if not in the header, where is it supposed to go? You put the definition in a source file but how do you combine the source into your program with an #include directive?
Header guards are used to avoid multiple declarations of the same symbol (which occur if you include the same header more than one on the same source file)

The multiple definition occurs on link time, if multiple source file define the same symbol you'll get this error.

The linker is the tool which makes symbol defined in multiple source files to work together.

This article may help you: http://www.cplusplus.com/forum/articles/10627/
I've examined the article before, but (unless you linked the source files explicitly) how does including the header in both sources connect them to each other?
Is the linker connecting them, not the header
Keep in mind that header files do not get compiled -- source files (.cpp, .cxx, etc files) get compiled.

So:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// lcm.hpp
#ifndef LCM_HPP
#define LCM_HPP

int LCM( int a, int b )
  {
  int m = a;
  int n = b;
  while (m != n)
    if (m < n) m += a;
    else       n += b;
  return m;
  }

#endif 
1
2
3
4
5
6
7
8
9
10
11
12
// english.cpp

#include <iostream>
#include "lcm.hpp"

void ask()
  {
  int a, b;
  cout << "Input two positive integers> " << flush;
  cin >> a >> b;
  cout << "The least common multiple is " << LCM( a, b ) << ".\n";
  }
1
2
3
4
5
6
7
8
9
10
11
12
// spanish.cpp

#include <iostream>
#include "lcm.hpp"

void pedir()
  {
  int a, b;
  cout << "Entra dos integeres positivos> " << flush;
  cin >> a >> b;
  cout << "El mínimo común denominador es " << LCM( a, b ) << ".\n";
  }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// main.cpp

void ask();
void pedir();

int main()
  {
  cout << "1 - English\n"
          "2 - Español\n"
          "> "
       << flush;
  int n;
  cin >> n;
  switch (n)
    {
    case 1: ask();   break;
    case 2: pedir(); break;
    }
  return 0;
  }

To compile this, you'll do something like

g++ main.cpp english.cpp spanish.cpp

or

g++ -c main.cpp
g++ -c english.cpp
g++ -c spanish.cpp
g++ main.o english.o spanish.o

Of course, the LCM function will be defined twice: once in "english.cpp" and once in "spanish.cpp", since "lcm.hpp" was #included by both files.

I'm not so sure this was a very helpful answer. Just remember that #included files are simply expanded in place into the .cpp file that #includes it. Hence, anything other than prototypes and extern directives is bad news.

Good luck!
So... you have to link all the source files regardless of the headers you use?
And with the header guard, wasn't the header defined only once? Or is the header guard only relevant to the individual file in which it is #included?
Let me clarify what I'm thinking of:
When you create a program you can #include <iostream> and #include <vector> without also linking in vector.cpp or iostream.cpp. (I use vc++ so I mean you don't need to add such a source file to your project.) Is there any way to create such a self-containing header? Or am I misinterpreting/not seeing something?
Last edited on
The scope of macro definitions -- or, in fact, of all definitions -- is limited to the translation unit that defines them. This means a guarded header included in one file can also be included in a different file, provided that both files aren't included by the same translation unit, in which case only one inclusion (the earliest) does anything.
So, we have a.h, which is included by b.cpp and c.cpp. If this is the final state, there are two final translation units:
Unit A
<body of a.h>
<body of b.cpp>
Unit B
<body of a.h>
<body of c.cpp>

If both b.cpp and c.cpp were included by a d.cpp, there would be only one translation unit:
<body of a.h>
<body of b.cpp>
<body of c.cpp>
<body of d.cpp>


I'm not so sure about iostream, but most implementations (at least any implementation that doesn't support the export keyword) put the entire implementation of each STL container in the corresponding header. That's why there's nothing else to link. If there was something else to link, the compiler would link it for you automatically.
So then..... in theory, I could do function definitions in a header file and, as long as I had a header guard, I would not get any issues?
No. Because translation units have to be linked together, any duplicated definition that isn't an inline function (or inline member function) or a template will produce a linker error.
Ahhh....
So then, in any case, if I created my own header and its accompanying implementing source, I would have to link the source to my main to get it to work?
tummychow wrote:
Or is the header guard only relevant to the individual file in which it is #included?
That is correct. Each file compiles separately. If a file #includes another file, that file is considered part of the first. The #include directive instructs the CPP to insert the contents of the named file into the current file at the current location (in place of the #include directive).

tummychow wrote:
So then, in any case, if I created my own header and its accompanying implementing source, I would have to link the source to my main to get it to work?
Yes.

Give helios's post another read. Hope this helps.
OK, so then the header is never compiled. I presume that this means that you need to link the source to make the actual implementation available, but you still need the header for the declaration?
Does this mean there is no way to create a header that can operate alone, without linking a separate source implementation to your project?
Does this mean there is no way to create a header that can operate alone, without linking a separate source implementation to your project?
No, inlined functions and templates can (have to) be defined in the header.
An example are some of the Boost libraries, which work by only including a header without linking anything
I understand those but, as I noted above, what about the stream types? How would you create those classes and their various functions without linking in an additional source as is (apparently) necessary in the case of user-defined headers?
If your functions are inlined, you don't need a seperate source file to link to. You can have the function body right in the header file:

1
2
3
4
5
6
7
8
9
10
11
12
13
// MyClass.h
class MyClass
{
public:
  inline void ExampleA() { /* This is inlined*/ }
  inline void ExampleB();
};


inline void MyClass::ExampleB()
{
  // this is also inlined
}
So then is that how the stream headers work?
Would I need to inline all my functions to get my header to stand alone?
Streams are not inline. std::*stream are all typedefs of std::basic_*stream<char>.
Wait... so they're all templates?
Topic archived. No new replies allowed.