Search code examples
c++linker-errorsunresolved-external

Linker error when inlining function from cpp file


Well I'm getting a linker (unresolved external symbol) error when doing the following:

-I have a class "Object" - it is defined in "object.h".

it has a constructor like: explicit Object(double x, /* lots more */);

in file "object.cpp" I want to give that constructor a body: Object::object(double x) : _x(x) {}

This works.. However if I add the keyword "inline" in the "object.cpp" file:

inline Object::Object(double x) : _x(x) {}

suddenly a linker error pops up! "error LNK2019: unresolved external symbol"

Why? - does it mean I can't use inlining with constructors?

EDIT: actually I notice it is the case for all methods. However if I move all methods to the object.h header fil it DOES work. You can't inline function from outside the header file where the object is defined?

EDIT2: alright a big update, I decided to build a quick test case:
main.cpp:

#include "a.h"
int main ()
{
    a t;
    t.test(5);
    return 0;
}

a.h

class a {
public:
    void test (int x);
};

a.cpp

#include <iostream>
#include "a.h"
inline void a::test(int x) {
    std::cout << x << std::endl;
}

This gives the following error:

main.obj : error LNK2019: unresolved external symbol "public: void __thiscall a::test(int)" (?test@a@@QAEXH@Z) referenced in function _main

Removal of the "inline" keyword makes the program work.. As does combining "a.h" and "a.cpp" into 1 file.

I really can't think of more information to give :/


Solution

  • You need to understand the rules about definitions for functions marked inline.

    Marking a function inline means that you can define the function in more than one translation unit in your program (but just once per translation unit) but all definitions must be the same and you must provide a definition in every translation unit in which the function is used.

    In your example the translation unit from main.cpp uses a::test(int) but there is no definition in that translation unit. There is a definition in the translation unit from a.cpp but here it is marked inline which means that you can't leave a definition out of the translation unit from main.cpp.

    I'm not sure why you want to add inline to the definition in a.cpp because it is not necessary or useful. inline allows you to place function definitions in shared header files but it has no use if you want to put the function in a source file.