0

Im trying to run a very simple snippet of code. I've been getting a linker error. My code looks like this:

main.cpp -->

#include <iostream>
#include "Complex.h"

using namespace std;

int main()
{
   Complex c1(1.0, 5.0);  // this should create Complex object 1.0 + i5.0
   return 0;
}

Complex.h -->

#include <iostream>

class Complex {
private:
    double real;
    double imaginary;

public:
    Complex(double, double);
    void setReal(double);
    void setImaginary(double);

};

Complex.cpp -->

#include "Complex.h"
#include <cmath>

Complex::Complex(double x, double y) {
    setReal(x);
    setImaginary(y);
}
void Complex::setReal(double x) {
    real = x;
}
void Complex::setImaginary(double x) {
    imaginary = x;
}

The error I've been getting looks like this: Error photo

I have been trying to run my main for a while but I keep getting the linker error. I have no clue what's causing it. I would appreciate any suggestions.

Max Bentata
  • 435
  • 4
  • 6

1 Answers1

2

Just do

g++ main-3.cpp complex.cpp

mind the filename main-3, this is inconsistent in your question. You have to feed all cpp files you are using into the g++ commandline to tell g++ where the code for the functions defined in the header lies. Read up on .o files, static linking and understand what that means.

Here is a little guide I follow to understand file inclusion and other factors:

c++ compilation is moronically simple:

  1. read .cpp file
  2. replace every #include statement with the text of the specified file (just dump it in)
  3. If the resulting text still has #include directives (now from the header files), goto step 2.
  4. Compile the hughe messy blob into a ´.o´ object file, replace calls to functions with symbols and add to that file a table of known symbols and where they are defined.
  5. if there are more .cpp files specified, start a new empty text blob. Goto step 1.
  6. call the linker ´ld´ to link all object files together, replace symbols with the actual addresses.

Strictly speaking, above is a little bit of a lie nowadays and a lot is left out and no optimizations mentioned. But it is still a useful guide to the compiler's behaviour.

To use it to interpret your error: Complex.h got dumped into your blob, via the #include in main.cpp , but Complex.cpp did not. g++ generated an internal temporary .o file for you that contained something along the lines of

PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP Complex::Complex

... and ran the linker ´ld´ with that .o file. ld Could not find the address of the symbol Complex::Complex, it needs a memory address to jump to. If you compile Complex.cpp as well, the resulting Complex.o will have a symbol table with, for example, this entry:

Complex::Complex = 0xaaff

The linker, given Complex.o can now replace the symbol in main.o with an address.

PUT 1.0 on Stack
PUT 5.0 on Stack
JUMP 0xaaff
AndreasT
  • 9,417
  • 11
  • 46
  • 60