128

Since templates are defined within headers and compiler is able to determine if inlining a function is advantageous, does it make any sense? I've heard that modern compilers know better when to inline a function and are ignoring inline hint.


edit: I would like to accept both answers, but this is not possible. To close the issue I am accepting phresnel's answer, because it received most votes and he is formally right, but as I mentioned in comments I consider Puppy's and Component 10's answers as correct ones too, from different point of view.

The problem is in C++ semantics, which is not strict in case of inline keyword and inlining. phresnel says "write inline if you mean it", but what is actually meant by inline is not clear as it evolved from its original meaning to a directive that "stops compilers bitching about ODR violations" as Puppy says.

doc
  • 7,500
  • 5
  • 42
  • 67

4 Answers4

101

It is not irrelevant. And no, not every function template is inline by default. The standard is even explicit about it in Explicit specialization ([temp.expl.spec])

Have the following:

a.cc

#include "tpl.h"

b.cc

#include "tpl.h"

tpl.h (taken from Explicit Specialization):

#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}

template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif

Compile this, et voila:

g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)'
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

Not stating inline when doing explicit instantiation may also lead to issues.

So in summary: For non fully specialized function templates, i.e. ones that carry at least one unknown type, you can omit inline, and not receive errors, but still they are not inline. For full specializations, i.e. ones that use only known types, you cannot omit it.

Proposed rule of thumb: Write inline if you mean it and just be consistent. It makes you think less about whether to or not to just because you can. (This rule of thumb is conforming to Vandevoorde's/Josuttis's C++ Template: The Complete Guide).

Sebastian Mach
  • 36,158
  • 4
  • 87
  • 126
  • It's true for explicit specializations - they are like plain functions. But here -> `template inline T g(T) {}` inline is not required and you could have written `template T g(T) {}` – doc May 10 '12 at 15:10
  • 2
    One could have written, true. But that doesn't imply inlineness, even if it appears like that. Vandevoorde and Josuttis also state exactly that in _C++ Templates: The complete Guide_ – Sebastian Mach May 10 '12 at 15:13
  • There's a bit weaker statement that templates can have multiple definitions (3.2/5) --> http://stackoverflow.com/a/10211420/205955 I agree that this does not imply that they are formally inline. However, it all comes down to this in practice. So, both answers are correct from different points of view. – doc May 10 '12 at 15:21
  • 1
    I added a rule-of-thumb. I personally dislike omitting `inline` just because you can, and then re-introducing it when you must. I really prefer to say _inline_ when you mean it. – Sebastian Mach May 10 '12 at 15:27
  • 49
    The explicit specialization is not a template. – Puppy Jan 22 '13 at 21:26
  • 2
    @DeadMG: Yet a normal function is preferred over a full specialisation upon lookup, so if they are not template, nor non-template, what are they then? – Sebastian Mach Jan 23 '13 at 11:49
  • For some reason the above link did not work for me. Deciphering the URL I understood the link needed to point to page 72: http://books.google.co.uk/books?id=yQU-NlmQb_UC&lpg=PP1&pg=PA72 – malat Sep 26 '14 at 08:23
  • 1
    I'm not sure I understand what you mean by "Write inline if you mean it...". When could you possibly *not* "mean" `inline` for a template? – Kyle Strand Jan 21 '16 at 18:23
  • 1
    @KyleStrand: Just like with normal functions. This is a bit like asking When could you possible _not_ "mean" `mov eax, alpha` for an addition. With non-inline template functions, I want the same benefits of non-inline non-template functions. – Sebastian Mach Jan 22 '16 at 14:08
  • 18
    This answer is incorrect. An explicit specialization of a template is a function, not a template. That function does not become `inline` just because the template that was specialized is marked with `inline`. So `inline` on the template is completely irrelevant. Whether that function should be `inline` or not has nothing to do from it being generated via a template specialization (and there are better answers than this that address when to use `inline`). @Puppy 's answer below is correct, this one is not. Adding `inline` on a template is irrelevant, and `clang-tidy` will actually remove it. – gnzlbg Aug 09 '17 at 09:32
  • 7
    Also, the example just showcases ODR issues for normal functions (the behavior there has nothing to do with templates). To attempt showing that `inline` is not be irrelevant, the example should cover the case of explicitly specializing `template<> void f<>(int) {}` _without_ the `inline` keyword. But even then changing the `inline` specifier on the template does not make any difference, because whether you mark the template `inline` or not is irrelevant. – gnzlbg Aug 09 '17 at 09:44
39

It's irrelevant. All templates are already inline- not to mention that as of 2012, the only use of the inline keyword is to stop compilers complaining about ODR violations. You are absolutely correct- your current-generation compiler will know what to inline on it's own and can probably do so even between translation units.

josaphatv
  • 526
  • 3
  • 17
Puppy
  • 138,897
  • 33
  • 232
  • 446
  • 12
    The standard does not state that all templates are inline. – Sebastian Mach May 10 '12 at 14:41
  • 16
    @phresnel: But templates have the same semantics as `inline`-marked functions (that is, multiple equivalent definitions may be passed to the linker, which will select one). That, not inlining, is the real function of the `inline` keyword. – Ben Voigt Jul 10 '12 at 21:12
  • 2
    @BenVoigt: I know about the ODR meaning of `inline`. Maybe have a peek at my answer below (or above, depending on chosen sorting). For non-specialized templates, you are of course right, but it is formally not the same. – Sebastian Mach Jul 11 '12 at 15:52
  • 1
    There is no difference between a template function and an `inline` one, so whether or not the Standard states it is irrelevant. – Puppy Jan 22 '13 at 21:25
  • 4
    @DeadMG: There is no requirement in C++ that a function template must be implemented in a header file; it can be implemented anywhere. To reflect this, I tend to recommend tagging `inline` what is supposed to be inline. It usually makes no difference, but in standardese, they are not the same, and they are not all inline. I accept your stance on it saying "It's irrelevant", but per the standard, not all templates are inline, only for you as a C++-user they appear as if. – Sebastian Mach Jan 23 '13 at 12:05
  • 10
    Your comment on the accepted answer that explicit specialization is not a template (which is obvious *after* being told so, of course....) is perhaps the most helpful thing on this page. Would you mind adding it to your answer as well? – Kyle Strand Jan 21 '16 at 18:21
  • The inline keyword _does_ have some use outside of just preventing ODR-violations. For example, clang provides `-finline-hint-functions` to force all functions marked inline to _actually_ inline. – pro-gramer Aug 16 '20 at 11:43
7

As you suggested, inline is a hint to the compiler and nothing more. It can choose to ignore it or, indeed, to inline functions not marked inline.

Using inline with templates used to be a (poor) way of getting round the issue that each compilation unit would create a separate object for the same templated class which would then cause duplication issues at link time. By using inline (I think) the name mangling works out different which gets round the name clash at link time but at the expense of vastly bloated code.  

Marshall Cline explains it here better than I can.

Community
  • 1
  • 1
Component 10
  • 9,649
  • 4
  • 42
  • 58
  • @Xeo: That didn't used to be the case. Check here: http://gcc.gnu.org/onlinedocs/gcc-4.0.4/gcc/Template-Instantiation.html#Template-Instantiation I assume that has changed more recently, that's why I was talking in the past tense. – Component 10 May 10 '12 at 14:56
  • 2
    @Xeo: Can you point me to the part of The Standard which states that function templates are always inline? Because, they are not. – Sebastian Mach May 10 '12 at 15:11
  • @phresnel: Interesting, I could swear I've read that in the standard. Maybe I mixed it up with the fact that function templates are exempt from the ODR (`§14.5.5.1 p7 & p8`). My bad, I removed the wrong comment. – Xeo May 10 '12 at 15:51
  • @Component 10 Why you think it's poor way of getting round compilation issue – PapaDiHatti Jun 21 '19 at 16:17
  • The compiler may provide flags that make inline more than just a hint (e.g. clang has `-finline-hint-functions`). Whether it is good idea to use such flags, is another question though. – pro-gramer Aug 16 '20 at 11:48
0

This is what the C++ standard says:

[dcl.inline/1]

The inline specifier shall be applied only to the declaration of a variable or function.

plexando
  • 959
  • 4
  • 20