I wrote up a quick example today just to see if it would compile and I was actually quite surprised when I found that it did!
Here is the example:
hello.h
#ifndef HELLO_H
#define HELLO_H
// Function prototype
void say_hello();
#endif
hello.cpp
NOTE: This does NOT include "hello.h" like it would in every C++ example I have ever seen in the history of forever!
// #include "hello.h" <-- Commented out. The corresponding header is NOT included.
#include <iostream>
void say_hello() {
std::cout << "Hello!" << std::endl;
}
main.cpp
#include "hello.h"
int main() {
say_hello();
}
I then compiled "hello.cpp" into a static library as follows:
g++ -c hello.cpp
ar -rvs libhello.a hello.o
Then I compiled the "main" application and linked it to the library
g++ -o main main.cpp -L. -lhello
And ran it and it executed fine!
./main
Hello!
While I was surprised... I do understand why this works. It is because the function in "hello.cpp" is not declared static so it has external linkage and can be seen from outside. Making it static will cause the link to fail due to an undefined reference.
So here's the question... If this does work, then why does everyone everywhere ALWAYS include the ".h" header file with the function declarations in the ".cpp" implementation file. Clearly if it is just defining free functions, this is not necessary and everything will work fine if the header file is not included.
So why do we always include it? -- Is it simply a general lack of understanding of how the linker works? Or is there something more?