35

I think my question has been asked here before, I did read them but still little confused and therefore asking to make it clear.

The C++ standard says all member functions defined inside class definition are inline

I have also heard that compiler can ignore inlining of a function. Will that be true in the above case or it will be always inlined if defined inside class definition?

Also, what was the reason behind this design, making all functions defined inside class definition inline? And what inlining has to do with source and header files?

Update: So one should always define their functions outside class if not to be inlined, right?

Update 2 by JohnB: Two functions declared inside class definition could never call each other as they would have to each contain the whole body of the other function. What will happen in this case? (Already answered by Emilio Garavaglia)

vidit
  • 6,293
  • 3
  • 32
  • 50

6 Answers6

60

Confusion arises because inline has two effects:

  1. It tells the compiler that the function code can be expanded where the function is called, instead of effectively being called.
  2. It tells the compiler that the function definition can be repeated.

Point 1. is "archaic" in the sense that the compiler can in fact do what it likes in order to optimize code. It will always "inline" machine code if it can and find convenient to do and it will never do that if it cannot.

Point 2. is the actual meaning of the term: if you define (specify the body) a function in the header, since a header can be included in more sources, you must tell the compiler to inform the linker about the definition duplicates, so that they can be merged.

Now, by the language specification, free functions (not defined in class bodies) are by default not defined as inline, so defining in a header a thing like

void myfunc()
{}

if the header is included in more sources, then linked in a same output, the linker will report a multiple definition error, hence the need to define it as

inline void fn()
{}

For class members, the default is the opposite: if you just declare them, they will not be inlined. If you define them, they will be inline.

So a header should look like

//header file

class myclass
{
public:
    void fn1()
    {} //defined into the class, so inlined by default

    void fn2();
};

inline void myclass::fn2()
{} //defined outside the class, so explicit inline is needed

And if myclass::fn2() definition goes into a proper source, must lose the inline keyword.

Nick
  • 27,566
  • 12
  • 60
  • 72
Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
  • 1
    +1 for the gr8 explanation. You already answered update 2. So the correct definition of inline is "It tells the compiler that the function definition can be repeated." – vidit Mar 16 '12 at 10:02
  • 3
    One can consider the _inline_ word in the syntax to mean "this function's definition will be inlined into multiple translation units without breaking ODR". I.e. inlining on the source code level, not on the machine code. – Ruslan Sep 08 '16 at 09:06
  • @Ruslan ,correct clarification. When you declare a func. included in a header file as inline, in whichever TU source you INCLUDE the header file, the compiler will substitute the source of the func. WHEREVER it has referenced in the TU source before compiling & not set up a func. definition on a call stack. If inline declaration is not used & if due to inclusion of the header file in multiple TU sources, multiple func. definitions end up getting set up & the linker will flag error of violation of ODR. So, if your want to inline the function, you'd declare the function inline in the 1st place. – rps Jun 27 '20 at 16:10
21

The inline keyword has for a function 2 meanings:

  1. Code replacement: Wherever inline function is invoked, don't generate a function call for it but simply place the contents of the function at the place of its call (this is something similar to macro replacement, but type safe)
  2. One definition rule: Don't generate multiple definition for a inline function, only generate a single definition common for all (exception: static functions)

The 1st terminology ("Code replacement"), is simply a request to the compiler. which can be ignored as compiler is better to judge whether to put the text or a function call. (for example, virtual functions or recursive functions cannot be inlined).

The 2nd terminology ("One definition rule") is guaranteed to happen by any conforming compiler. This will generate only 1 definition for all translation units. This facility eases coder's work sometimes, as for smaller function one may not want to put its definition in .cpp file (e.g. getters, setters).
Moreover, for template function which are header only constructs, this effect is mandatory. Thus template functions are inline by default.

Examples:

class A {
public:
  void setMember (int i) { m_i = i; }
};

In this example mostly compiler would suffice both terminologies

class A {
  inline virtual ~A () = 0;
};
A::~A() {}

Here compiler can only suffice the 2nd requirement.

iammilind
  • 68,093
  • 33
  • 169
  • 336
8

The only reason to make the method function inline is if you define it in the header.

If you define a method function in a header, and you do not put inline keyword, and you include the header in several header or source files, you would get multiple definition of the method.

c++11 standard in 9.3/2 Member functions [class.mfct] tells :

A member function may be defined (8.4) in its class definition, in which case it is an inline member function (7.1.2) ...

BЈовић
  • 62,405
  • 41
  • 173
  • 273
3

When the definition is inside the class, it is treated as if it were declared inline, because it is assumed that class definitions live in header files that are used from more than one translation unit, so any non-inline definitions here would violate the One Definition Rule.

The compiler is, as always, free to inline whatever it thinks as long as it takes care that functions that are either explicitly or implicitly inline will not lead to linker errors. How it does that is left open by the language spec -- inlining the function of course works, but it is also acceptable to demote the symbol visibility or rename the symbol to a translation unit specific name (as if the function were in an anonymous namespace), or (as most of them do) communicate to the linker that multiple copies of that function may exist and that it should discard all but one of them.

So, in short, it is not treated any different from functions that are explicitly declared inline.

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
1

The compiler can ignore inlining if specified by the inline keyword. If the method implementation is present inside the class definition, that's a different thing, and can't be ignored. (well it can, but that makes the compiler non-conforming)

The reason behind the desing - I'm assuming a mechanism was needed where you can actually force the compiler to actually inline your functions, since the inline keyword doesn't mandate it. But in general, inline method definition is done only in cases like getter and setter methods, or some trivial 2-liners. And templates, but that's a different issue.

Inlining has to do with headers and source files in that the definition of the function must be visible to the compiler so it knows how to actually inline the call. It's more difficult to inline a function defined in an implementation file than one defined in a header.

EDIT: On a side note, the paragraph the op is reffering to is 7.1.2.3:

A function defined within a class definition is a inline function [...].

EDIT2:

Apparently, there are some difference between an inline function and inline substitution. The first is a property of a function, that doesn't only include inline substitution, the second means that the function body is actually pasted where it is called.

So the function can be inlined but not have its body pasted instead of being called.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • `But in general, inline method definition is done only in cases like getter and setter methods, or some trivial 2-liners` does that mean a big function inside class definition wont be inline? – vidit Mar 16 '12 at 08:58
  • @vidit it would, but defeat the purpose. Move a big implementation in an implementation file. – Luchian Grigore Mar 16 '12 at 09:07
  • @vidit yes, define functions outside if you don't want them inlined. – Luchian Grigore Mar 16 '12 at 09:15
  • 1
    i -1ed this. see the other answers for the reason – Johannes Schaub - litb Mar 16 '12 at 09:41
  • I can't believe that the standard says that two functions declared in the class definition are required to be actually inlined. Wouldn't that for example mean that two functions declared this way could never call each other as they would have to each contain the whole body of the other function which is clearly impossible. – jcoder Mar 16 '12 at 09:42
  • @JohannesSchaub-litb can you be more precise? – Luchian Grigore Mar 16 '12 at 09:47
  • @JohnB that's a very good point. Maybe it can be an inline function (I mean, that's what the standard says) and its body not be pasted in the actual code?... – Luchian Grigore Mar 16 '12 at 09:48
  • @JohnB - Good point.. I should include this in my question, if you dont mind? – vidit Mar 16 '12 at 09:49
  • emilios answer has all the details. and contradicts your answer, which is incorrect. – Johannes Schaub - litb Mar 16 '12 at 09:51
  • @JohannesSchaub-litb can you tell me exactly where my answer is wrong? I can't see from emilio's answer. Also, please not the difference between inline function and inline substitution. – Luchian Grigore Mar 16 '12 at 09:54
  • 1
    The reason for _my_ downvote is that you say "_a mechanism was needed where you can actually force the compiler to actually inline your functions_". This is wrong: the functions defined in class definition can't be forced to be inlined if using the standard syntax only — due to the _as if_ rule. What this was needed for is to avoid multiple definition of these functions when you include your header defining the class in multiple translation units. It would be counterproductive to require all such functions to be explicitly marked `inline`, so they are inline implicitly. – Ruslan Sep 07 '16 at 11:45
0

the two things you reffer to are different aspects and not to be confused with.

1) The C++ standard says all member functions defined inside class definition are inline

2) I have also heard that compiler can ignore inlining of a function

1) is when you define the member functions inside the class declaration itself. ie: in the header files. for that you do not have to provide any keyword( ie: inline)

2) You can specify a function as inline by explicitly using the inline keyword. this is actually a request to the compiler. the compiler may or may not make the function inline according to some rules of optimization.

Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112