C++ Inline Member Function in .Cpp File

Why is it not possible to inline function definitions in .cpp file?

The inline keyword is really confusing, although, for this use-case it is still clear if you know the meaning.

inline influences the requirements of the code that needs to be generated. More specifically, it tells to your compiler that it should not foresee a function pointer for that function. As always, it is allowed to copy the content into the caller. Because of inline, the original function does not have to be created.
So you don't have a function pointer into test.o.

In main.o, you call this function. Therefor, it tries to resolve the function pointer which was not created, which causes this linker error.

Finding these cases can be done with for example a compiler warning by clang: -Wundefined-inline

EDIT

Will an inline function not have a function pointer? No, you can perfectly take the address of this function and use it and pass it. Although, because of the inline character of the function, you cannot rely on this function pointer comparing equal in comparison with another address of the same function.

In this case, you will have somewhere the function pointer in your object file. However, in this case, the compiler doesn't require to give this the correct mangled name so it can be used from another compilation unit.

C++ call inline function from another cpp file

According to the C++ Standard (7.1.2 Function specifiers)

4....If a function with external linkage is declared inline in one
translation unit, it shall be declared inline in all translation units
in which it appears; no diagnostic is required.

and

4 An inline function shall be defined in every translation unit in
which it is odr-used and shall have exactly the same definition in
every case

In C ( section 6.7.4 Function specifiers of the C Standard ) function specifier inline for external functions has different semantic

7....An inline definition does not provide an external definition for the function, and does not forbid an external definition in another
translation unit. An inline definition provides an alternative to an
external definition, which a translator may use to implement any call
to the function in the same translation unit. It is unspecified
whether a call to the function uses the inline definition or the
external definition

How to define an inline free function (non member function) in C++?

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 than 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();

or

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

/* ... */ foo();

Why are C++ inline functions in the header?

The definition of an inline function doesn't have to be in a header file but, because of the one definition rule (ODR) for inline functions, an identical definition for the function must exist in every translation unit that uses it.

The easiest way to achieve this is by putting the definition in a header file.

If you want to put the definition of a function in a single source file then you shouldn't declare it inline. A function not declared inline does not mean that the compiler cannot inline the function.

Whether you should declare a function inline or not is usually a choice that you should make based on which version of the one definition rules it makes most sense for you to follow; adding inline and then being restricted by the subsequent constraints makes little sense.

Moving inline methods from a header file to a .cpp files

If you moved the function definition from a header to a cpp file, you MUST remove the inline keyword all all locations for that function. With older linkers it might make things slightly slower, but with modern linkers you should notice no real difference in performance.*

There are certain cases where a public member function can be inline, but that's just a bad idea. Don't do it. Arguments can be made for marking certain private member functions as inline, but in reality what you really want in those to be __attribute__((always_inline)) or __forceinline

*In extremely rare cases it will make a difference, but 99% of the time it won't, and 99.9% of what's left you don't care. If measurements show you hit that one-in-ten-thousand, you can use the aformentioned __forceinline.

Compilation of C++ member functions defined outside the class body

Recall that the content of the entire header, along with any files that it may include, is virtually "copy-pasted" into each translation unit* that includes the header at the point of inclusion.

That is why the effect of including the header in multiple CPP files is the same as if you literally copy-pasted function definition into each CPP, i.e. it is the same as if you wrote multiple identical definitions of the same member-function.

The problem is solved by declaring the function inline, because C++ allows multiple definitions of inline functions, as long as they are identical to each other. Moving the body of the function into the declaration of the class also works, because such functions are automatically considered inline.

* In this context, "translation unit" is a fancy name for your CPP file.



Related Topics



Leave a reply



Submit