3

Why it is not possible to inline function or class member function definitions in .cpp files? For instance in my test examples below, the linker will give me back an undefined reference error if I try to inline a function or class member definition in the cpp file:

test.h

void print();

class A
{
    public:
        void print() const;
};

test.cpp

#include <test.h>

inline void print()
{
    // implementation
}

inline void A::print() const
{
    // implementation
}

main.cpp

#include <test.h>

int main(int argc, char** argv)
{
    print(); // undefined reference to `print()'
    A a;
    a.print(); // undefined reference to `A::print() const'

    return 0;
}

I have read some answers here, yet I am still uncertain how it works.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Andi
  • 8,154
  • 3
  • 30
  • 34
  • Possibly because it **is** possible to inline functions across .cpp files. If you *remove* the `inline` from the functions, they will work [and *possibly* even be inlined](https://stackoverflow.com/a/3993045/597607). – Bo Persson Jun 03 '18 at 11:55

3 Answers3

15

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

You can inline functions in a cpp file.

What you can not do is access those inline functions from a different cpp file.

An inline function must be present in every file that uses it. That is why they often go in header files so any source needing to use it, includes the header containing it.

Galik
  • 47,303
  • 4
  • 80
  • 117
4

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.

JVApen
  • 11,008
  • 5
  • 31
  • 67
  • So there will be never a function pointer to a function when that function is inlined regardless if its contents are copied or not? – Andi Jun 03 '18 at 11:49
  • There can be, thats upto your compiler. Although, you can't rely on it. However, if you take the address, some extra uglyness comes into play, let me add that. – JVApen Jun 03 '18 at 11:50
  • Oh okay. But the linker will always complain in that case even though the function pointer might exist? – Andi Jun 03 '18 at 11:53
2

From cppreference.com:

The definition of an inline function or variable (since C++17) must be present in the translation unit where it is accessed (not necessarily before the point of access).

Your functions are defined in test.cpp but you are accessing them from main.cpp.

Mikhail Vasilyev
  • 503
  • 4
  • 11