I just learned that defining a c++ function inside a class's header file make the function inline. But I know that putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it. Is this the same for header defined c++ functions and is there a difference in behavior between a standalone c++ function and a c++ function that is part of a class?
views:
202answers:
4C++ compilers are free to choose what will be inline and what won't, no matter what hints you give them. It shouldn't matter if the function is part of a class or not, or whether it is in a header file or source file; the compiler doesn't pay attention to those things while making its decision.
"defining a c++ function inside a class's header file make the function inline"
That's not true. Defining a function (that is to say, providing the body of the function instead of just a declaration) inside a class definition makes it inline. By "makes it inline", I mean it's the same as giving it the inline keyword. But class definitions don't have to be in headers, and headers can contain other things than class definitions.
So in this example, the function foo
is implicitly inline. The function bar
is not implicitly inline:
struct Foo {
void foo() {}
void bar();
};
void Foo::bar() {}
"putting the inline keyword next to a function is only a suggestion and the compiler wont necessarily follow it"
inline
has two effects. One of them is a hint to the compiler which it can ignore. The other is not optional, and always has its effect. The "hint" is that the compiler is advised to replace calls to that function with a copy of the code for the function itself.
The guaranteed effect is that an inline function can be defined in multiple translation units, and those be linked together, without a multiple definition error, and all but one of the copies is removed by the linker. So, if the example above appears in a header file which is shared between multiple translation units, bar
needs to be explicitly marked inline. Otherwise, the linker will discover multiple definitions of bar
, which is not allowed.
Despite the name, inline
in C++ is mostly about the second, compulsory effect, not the first, optional one. Modern optimising compilers have their own ideas about which calls should be inlined, and don't pay a whole lot of attention to inline
when making that decision. For instance I've seen it have an effect in gcc at moderate optimisation levels, but at low levels approximately nothing is inlined, and at high levels approximately everything is (if the definition is available when the call is compiled) unless it makes the function too big.
Whether a function is defined in a header or in a cpp file has absolutely no effect on anything by itself. You can safely imagine that what #include does is copy and paste the header file into the cpp file in the preprocessor, before the compiler ever sees it. If a function is defined in the same translation unit as a call to it, then the function code is available to be inlined by the compiler. If they're in different translation units, then the code is not available and the call can only be inlined by the linker, with whole-program optimisation or similar. A "translation unit" more or less means, "a cpp file, after all the headers have been copy and pasted into it".
If you place the definition of a free non-template function in a header file, you will end up with a function definition in each .cpp file that includes the header (directly or indirectly). This can lead to problems when linking.
However, if you declare the function to be inline, the linker will make sure you only use a single definition even if it is included at multiple places.
No, not always. The compiler treats it as a hint, just like the inline
keyword, but it mostly decides on its own, because it knows better than you what the costs and benefits may be. Inlining the code avoids the function call overhead, but makes the code bigger, which has negative performance impacts on the instruction cache.
These performance hints from the programmer are generally more and more often ignored by the compiler. What it does not ignore (or rather, what the linker does not ignore) is that a function declared inline
may appear in several compilation units, and should be treated as multiple copies of the same function without resulting in linker errors.