Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 :/

like image 583
paul23 Avatar asked Nov 18 '10 23:11

paul23


2 Answers

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.

like image 94
CB Bailey Avatar answered Sep 28 '22 16:09

CB Bailey


You have a lower-case o in the constructor name in the code, whether inline or not. C++ names are case-sensitive.

Try this:

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

I'm not clear what you mean by the /* lots more */ comment in the code you posted. if you have other parameters in this declaration, the constructor's definition has to match that.

like image 41
Steve Townsend Avatar answered Sep 28 '22 14:09

Steve Townsend