5

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

2
  • Take a look at this discussion of inline class member functions - it might help you to understand why one or other case is failing. msdn.microsoft.com/en-us/library/bw1hbe6y.aspx Commented Nov 18, 2010 at 23:40
  • I don't think that inline means what you think it means. Can you say why you are trying to achieve with it? Commented Nov 19, 2010 at 0:12

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I've always heard that for "basic" function (such as "get" to get an internal variable) it improves both speed & memory?
@paul23: In most modern environments compilers will consider inlining any function - whether marked inline or not - and with link time code generation even if they are defined in different source files. inline just allows you to place those function in places that are (historically) easier for compilers to inline, i.e. header files. It doesn't make any guarantees about which calls are actually inlined.
I still don't get it. Other Stackoverflow answer clearly suggest that the declaration should be done in the header file, and the class method implementation should be preceder by the inline keyword, as OP did here. Example - stackoverflow.com/a/953731/1469954. Then why it is failing? Can you a bit more clear on te translation unit thingy?
I used the refactoring function of VS2017 to move the functions from the .h to the .cpp file. VS2017 added the "inline" keyword by itself. What confused me, was that only functions that take arguments made the linker complain for LNK2019. Functions like a(void) were linked Ok. Manually removing the "inline" fixed the problem as you described.
2

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.

2 Comments

oops that was a typo when making the post. checks - yes it was.
@paul23. Please post the exact code that is currently failing, and the error that matches that code.
0

There is something incongruent in implementation. If this code is wrote inside class definition, then you don't need "Object::". Sometimes this could cause compiler errors. Just erase it and try again. If is wrote out of class definition, you can not declare inline here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.