I know that providing the function body in a header automatically mark a function as candidate for inlining
More or less; but you do that by providing the function body in a class definition, or by explicitly declaring it inline
if it's in a header. Otherwise, the function is subject to the One Definition Rule, and you'll get errors if you include the header in more than one translation unit.
Note that this doesn't force the compiler to inline all calls to the function; providing the definition in a header just allows it to inline it in any translation unit that includes the header, if it thinks it's worth it. Also, some compilers can perform "whole program optimisation", and inline functions even when a definition is not available at the call site.
Then, in this case, will func() be marked candidate for inlining ? It isn't a virtual function, but still calls a virtual function. Does it make it inline-able ?
Yes, all functions are candidates for inlining. If they call themselves, then obviously you couldn't inline all the calls; nor if the function isn't known at compile time (e.g. because it must be called virtually, or through a function pointer). In this case, inlining the function would replace the direct call to func()
with a virtual call to doFunc()
.
Note that sometimes virtual calls can be inlined, if the dynamic type is known at compile time. For example:
struct MyImplementation : Interface {/*whatever*/};
MyImplementation thing;
thing.func(); // Known to be MyImplementation, func and doFunc can be inlined
Extra question: would it be worth it ?
That depends on what "it" is. If you mean compile time then, as long as the function remains short, you might get some benefit (possibly significant, if the function is called many times) for negligible cost. If you mean the cost of spending time choosing where to put it, then probably not; just put it wherever's most convenient.