4

I'm still fairly new to C++, so I apologize in advance if this is has a simple answer. I'm trying to use an overloaded operator. Here's the signature for that operator:

const Vector3D operator/(const Vector3D& lhs, const double rhs)

And here's the method where I'm trying to use it:

OrthonormalBasis::OrthonormalBasis(const Vector3D &a)
{
    Vector3D t;
    w = a / a.length();
    t = getCollinearVector(w);

    //More code goes here
}

When I try to compile, g++ comes back with the following error:

/file/path/orthonormalBasis.cpp:8: undefined reference to 
`operator/(Vector3D const&, double)' 
collect2: ld returned 1 exit status

The operator is defined in Vector3D.cpp, so I do have a definition.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
Mr Jones
  • 1,188
  • 3
  • 17
  • 33
  • http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix – chris Feb 01 '13 at 18:20
  • `a.length()` isn't a `double`, so the operator's signature doesn't match. – vonbrand Feb 01 '13 at 18:22
  • 5
    @vonbrand: If that were the case, he would get a compiler error, not a link error. – Benjamin Lindley Feb 01 '13 at 18:25
  • @vonbrand How do you know his implementation of `Vector3D` ? – Foggzie Feb 01 '13 at 18:25
  • Could you please show the implementation (body) of the overloaded operator function? – Masked Man Feb 01 '13 at 18:31
  • Either the definition of that function named `operator/` is missing entirely, or you forgot to pass an object file containing that compiled definition to the linker. – aschepler Feb 01 '13 at 18:31
  • I think the concept of the linker must be really confusing to a lot of programmers. I see a lot of questions here that boil down to "the linker can't find my function". And they are almost always resolved by fixing the build process so the linker is told about an object file it wasn't before. I think people get spoiled by IDEs. – Omnifarious Feb 01 '13 at 18:34
  • 1
    @Omnifarious: That's because most texts do shit to nothing as far as covering tool chains, and just focus on code. And you can count me among those people. After 7 years, I still struggle with that process, at least when it comes to figuring out how to link other libraries into my program. – Benjamin Lindley Feb 01 '13 at 18:35
  • 1
    It honestly took me way too long to learn about linking. And yes, I used an IDE from the beginning (as part of a class). It would have been so much more beneficial to do all of the basic manual compiling and linking before moving to an IDE. – chris Feb 01 '13 at 18:38
  • Please present us with a more complete example, including all the code necessary to reproduce the issue, and the command you are using to build your program. – Benjamin Lindley Feb 01 '13 at 18:45

2 Answers2

5

What you are seeing is a linker error. Linking is a stage of creating an executable that happens after compiling. The job of the linker is to take all references to symbols and resolve them into references to their definitions.

This means that as input to the linker, you have to provide all the symbol definitions. Some of those will come from libraries, and some from .cpp files. Unfortunately, the linker cannot actually parse C++. It expects the compiler to have done that. The compiler than produces a .o file. That .o file contains the results of interpreting symbol definitions and producing stuff the CPU can execute directly. That's the kind of definition the linker needs.

Typically compiling a non-trivial program (i.e. one with multiple .cpp files) into an executable involves creating a bunch of .o files with the compiler, and then linking them together into an executable.

In your case, your symbol is defined in Vector3D.cpp and it is used in orthonormalBasis.cpp. I can also tell from the error that you're using g++ on a Unix platform of some kind. At a minimum the compile and link steps will look like this:

g++ -c Vector3D.cpp
g++ -c orthoNormalBasis.cpp
g++ Vector3D.o orthoNormalBasis.o

I'm betting you're just doing this:

g++ orthoNormalBasis.cpp

This is shorthand for:

g++ -c orthoNormalBasis.cpp
g++ orthoNormalBasis.o

As you can see, this completely misses even trying to compile Vector3D.cpp much less trying to link the resulting .o file into your executable. That's why you're getting that error.

Omnifarious
  • 54,333
  • 19
  • 131
  • 194
  • I'm actually building my project using cmake. When I first asked my question, I was unaware that this was a linking issue. Thanks to your answer and @BenjaminLindley for his comment, I was able to narrow down my problem. For reference, I forgot to link an external library using `target_link_libraries`. – Mr Jones Feb 06 '13 at 00:22
  • @MrJones: Ahh. :-) So the careful detailed explanation of exactly what linking was about wasn't really needed. Well, I'm glad you solved your problem anyway. I suspect you were confused out of realizing it was a link error because you were overloading an operator which isn't something people commonly do. – Omnifarious Feb 06 '13 at 13:47
3

It's mostly that you've only declared the overloaded operator/, not defined it, and so the linker is not able to link the function's definition.

sheu
  • 5,653
  • 17
  • 32
  • The overloaded `operator/` is *declared* in Vector3D.h and *defined* in Vector3D.cpp. Am I missing something? – Mr Jones Feb 01 '13 at 18:36
  • 1
    @MrJones, Then it's not linking to the cpp. – chris Feb 01 '13 at 18:37
  • 1
    @MrJones - Or, more accurately, not linking to the `.o` file produced by compiling `Vector3D.cpp`. The linker is a program that pulls together all the `.o` files and libraries and resolves references to symbols into references to their definitions within those `.o` files and libraries. When you see 'undefined reference' it generally is a linker error where it couldn't resolve a reference to a symbol into a reference to its definition. – Omnifarious Feb 01 '13 at 18:46