I have read existing answers on the two meanings of inline, but I am still confused.
Let's assume we have the following header file:
// myclass.h
#ifndef INCLUDED_MYCLASS
#define INCLUDED_MYCLASS
class MyClass
{
public:
void foo(); // declaration
};
inline void MyClass::foo()
{
// definition
}
#endif
Why does void foo()
which is defined outside the class in the file, have to be explicitly defined with inline
?
It's because you defined MyClass::foo
in a header file. Or a bit more abstract, that definition will be present in multiple translation units (every .cpp file that includes the header).
Having more than one definition of a variable/function in a program is a violation of the one definition rule, which requires that there must be only one definition in a single program of every variable/function.
Note that header guards do not protect against this, as they only protect if you include the same header multiple times in the same file.
Marking the function definition as inline
though means that the definition will always be the same across multiple translation units.1.
In practice, this means that the linker will just use the first definition of MyClass::foo
and use that everywhere, while ignoring the rest,
1: If this is not the case your program is ill-formed with no diagnostics required whatsoever.
If you put MyClass::foo()
in a header file and fail to declare it inline
then the compiler will generate a function body for every compilation unit that #include
s the header and these will clash at link time. The usual error thrown by the linker is something along the lines of Multiple definition of symbol MyClass::foo()
or somesuch. Declaring the function inline
avoids this, and the compiler and linker have to be in cahoots about it.
As you mention in your comment, the inline
keyword also acts a hint to the compiler that you'd like the function to be actually inlined, because (presumably) you call it often and care more about speed than code size. The compiler is not required to honour this request though, so it might generate one or more function bodies (in different compilation units) which is why the linker has to know that they are actually all the same and that it only needs to keep one of them (any one will do). If it didn't know they were all the same then it wouldn't know what to do, which is why the 'classical' behaviour has always been to throw an error.
Given that the compilers these days often inline small functions anyway, most compilers also have some kind of noinline
keyword but that is not part of the standard.
More about inline
at cppreference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With