-2

I have a simple C++ class with a method that I want to Call from a Google Test Fixture.

When I declare the method in the cpp file the compiler throws an undefined symbol error:

Class.h

class Class {
 public:
  double test() {
    return 1.;
  }
}

Class.cpp

double Class::test() {
    return 1.;
}

GoogleTest.cpp

#include "Class.h"    

class GoogleTest : public ::testing:Test {
 protected:
  Class c;
}

TEST_F(GoogleTest, TestIt) {
  EXPECT_EQ(c.test(), 1.);
}

Meanwhile defining the method in the header I can compile like a charm:

Class.h

class Class {
 public:
  double test() {
    return 1.;
  }
}

GoogleTest.cpp

#include "Class.h"

class GoogleTest : public ::testing:Test {
 protected:
  Class c;
}

TEST_F(GoogleTest, TestIt) {
  EXPECT_EQ(c.test(), 1.);
}

What is the cause of this behavior? I do not want to define all my methods in header.


The whole error:

Undefined symbols for architecture x86_64:
  "Numeric::test()", referenced from:
      ConstantsTest_Gamma_Test::TestBody() in Test.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [runUnitTests] Error 1
DrDirk
  • 1,937
  • 3
  • 25
  • 36
  • What does the dot in front of the 1 signify? –  May 08 '17 at 14:36
  • @ArnavBorborah `.1` is a short for writing `0.1`, same goes for `1.` – yeputons May 08 '17 at 14:39
  • 6
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – UnholySheep May 08 '17 at 14:40
  • 1
    Firstly, I suppose that the definition of `test()` in the first case in Class.h should actually be a declaration. Secondly, the error should mean that Class.cpp was not compiled when compiling for testing. Check your make file. I haven't worked with Google Test, so I can't give the solution to the problem. – stefaanv May 08 '17 at 14:40
  • @ArnavBorborah I just wanted to be sure that the 1 will be treated as a `double` and is not mistaken as `Int` – DrDirk May 08 '17 at 14:40
  • 1
    Why are you defining the same function twice? – Jahid May 08 '17 at 14:40
  • 1
    Post the exact error as you get – Sniper May 08 '17 at 14:41
  • @Jahid This shall represent two code cases, one that functions a second that does not. I separated them with a line (------) – DrDirk May 08 '17 at 14:41
  • 1
    Did you `#include "Class.h"` at the beginning of your cpp file? – chtz May 08 '17 at 14:42
  • 1
    I see, you should reduce the definition in the header to a declaration `double test();` – Jahid May 08 '17 at 14:43
  • 2
    Did you forget to link `Class.o` (or whatever object file or library `Class.cpp` is compiled to) when creating your test binary? – Toby Speight May 08 '17 at 14:54
  • @TobySpeight turns out I did... – DrDirk May 08 '17 at 17:18
  • I'll write an answer based around that, then. – Toby Speight May 08 '17 at 17:37

2 Answers2

0

When linking the test program, you omitted to link Class.o (or whatever object file or library Class.cpp is compiled to). Possibly, if it's in a library, you specified it before the code which depends on it.

The reasoning is based on these lines:

  "Numeric::test()", referenced from:
      ConstantsTest_Gamma_Test::TestBody() in Test.cpp.o

The test itself (Test.cpp.o) was linked. ConstantsTest_Gamma_Test::TestBody is the name generated by the TEST_F() macro. The thing that's missing is Numeric::test(), which is in the class under test.

You'll need to add the class under test to your link line (in the right order with respect to other libraries). How you do that depends very much on what build system you're using, so I can't answer that in any more detail.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
-1

Most probably your compilation settings are incorrect and Class.cpp is not considered a file worth compilation in your IDE. Therefore, it's not getting linked into the resulting executable, which results in "undefined symbol". It's impossible to say for sure until you provide more details: the exact error message, what IDE do you use, etc.

yeputons
  • 8,478
  • 34
  • 67
  • Ok I rechecked all my Linkings and it turned out that I did not `add_executable(Class.cpp)` within my cmake file. The problem was, that I compiled two executables (one for testing, one for the program) and forgot to include the cpp files. Some classes, which were completely defined over the header file continued working so I did not recheck my executeable linkins. All in all my fault... – DrDirk May 08 '17 at 17:16