0

Please make me understand how header files works in C++. I am using osx and g++ compiler. I have

main.cpp

#include<iostream> 
#include "myfunc.hpp"
using namespace std;

int main() {
    square(10);
    return 0;
}

myfunc.hpp

#ifndef MYFUNC_HPP_
#define MYFUNC_HPP_

/*
void square(int x) {
    std::cout << x * x << std::endl;
};
*/
void square(int);

#endif // MYFUNC_HPP_

myfunc.cpp

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

using namespace std;

void square(int x) {
    cout << x * x << endl;
}

Now when I am trying to compile using g++ main.cpp , its giving

Undefined symbols for architecture x86_64: "square(int)", referenced from: _main in main-088331.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Because it is not able to find the function definition of square that is defined in myfunc.cpp. But, if I defined square function in header file, it works because now it finds the function definition.

I want to use the function defined in myfunc.cpp in main.cpp, so I am using the header file myfunc.hpp. How can I achieve this? Am I doing something wrong here? Maybe my concept is not that clear about headers since I am new to C++ programming.

Vishaal Shankar
  • 1,648
  • 14
  • 26
  • You need to include all the source files in your compilation string, not just `main.cpp`. – Ron Feb 08 '18 at 10:30
  • The `#include` is processed by the so-called preprocessor: cpp (run cpp main.cpp, you'll get it). It causes the included file to be some how copy-pasted inside your .cpp file. Once all the includes and processor directives replacedd, you get a translation unit. This file is then compiled to produce an object file: run g++ -c file.cpp => file.o. Then the object files are linked together using ld to produce a program. g++ is actulay a driver that run all these steps. To perform the last link phase, it must know all object file to produces: g++ main.cpp myfunc.cpp. – Oliv Feb 08 '18 at 10:38

1 Answers1

4

When you call g++ main.cpp, the compiler will try to compile and link the program, yet for linking, it lacks the source- or object file containing the definition of square. So it could compile main.cpp based on the function prototype given in the header file, yet it cannot link then.

To just compile main.cpp write

g++ -c main.cpp

To compile and link the complete program write:

g++ main.cpp myfunc.cpp

For more details concerning programs comprising several translation units confer, for example, this link.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58