1

In C++, I need to define some inline general functions. However, when I write the prototype in a header file and the implementation in a.cpp file, I encounter with "LNK2001 unresolved external symbol" error.

Shall I remove the .cpp file and implement the function in the header file?

I am trying to define some shared non-member math functions that can be used by other classes.

Header file:

inline void foo()
{
    //some code
}

.cpp file

//nothing
8
  • 3
    Please provide a minimal reproducible example. Commented Feb 15, 2019 at 8:38
  • This is a linking problem. Commented Feb 15, 2019 at 8:40
  • 1
    Yes, inline functions should be in the header file. There's (usually) no need for seperate prototype and implementation. Commented Feb 15, 2019 at 8:40
  • 1
    Shall I remove the .cpp file and implement the function in the header file? - Yes, if you only have inline functions in the header file, there's no reason for a cpp file. Commented Feb 15, 2019 at 8:43
  • 1
    Concerning inline: inline specifier. Commented Feb 15, 2019 at 8:46

2 Answers 2

7

The name of the inline specifier is somewhat misleading, as it suggests that the function be inlined. However, inline foremost specifies the linkage of the function (it's also a hint to the compiler to consider inlining). For a function declared inline no linkable symbol is generated in the compiled object.

Therefore, inline functions only make sense when defined (not merely declared) in a header file, which is included by, possibly, many compilation units. The inline specifier then prevents multiple (in fact any) symbols for this function to be emitted by the compiler in the respective object files.

If you need a small function only once for one compilation unit, you don't need to declare it anywhere else. Moreover, you don't need to declare it inline, but place it in the anonymous namespace to prevent it from being visible (in the object file generated).

So, either (that's most likely your use case)

// foo.hpp:
inline void foo(bar x) { /* ... */ }  // full definition

// application.cpp:
#include "header.hpp"

/* ... */ foo(X);

or

// application.cpp:
namespace {
    inline void foo(bar x)   // inline specifier redundant
    { /* ... */ }
}

/* ... */ foo(X);
Sign up to request clarification or add additional context in comments.

1 Comment

Nice answer! And yet: "For a function declared inline no linkable symbol is generated in the compiled object. ... The inline specifier then prevents multiple (in fact any) symbols for this function to be emitted by the compiler in the respective object files." Pretty sure this is not true, at least not always and only maybe sometimes. Often compilers still generate and mark symbols of inline free functions with some ODR relexation attributes or place them in COMDAT groups. Linker will then do COMDAT folding for any duplicates. Especially true for complex functions.
0

If you want your function to be in-line, you have to provide the definition in the header. If you have it in a separate cpp file it wont be in-lined. The link error is usually due to not including the cpp file during linking stage.

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.