When to use "inline"?

Asked

Viewed 1,385 times

11

Everybody says you don’t have to use inline functions since the compiler knows what to do better than the programmer. But if it has in the language it should serve for something.

Is it useful in any case? When to use then?

2 answers

9


The inline exists to give a hint to the compiler of what to do. It is in the C and C++ specification that it is like this.

The compiler does not need to follow this hint. It can linearize the function (put the content of the function where it should be called) with no hint, and can keep the call even with the hint.

Each compiler has its own rule in each platform and configuration. It is possible to ignore it completely without any criteria.

A tip can be useful in cases that it is not so obvious what to do.

  • Do not waste time on large function (few lines is already large).
  • Functions with loops, even if it is a line, will also not be linearized (unless the loop is replaced by simple code, if it can guarantee that it will iterate very few times, maybe 4).
  • Functions that make I/O access never pays off.
  • Function that is rarely used, which is not called in large loops, will give a minimal gain and may take place in the cache that would be useful for other better optimization.
  • Functions that can be used by third parties in external modules (DLL) and that there may be some update. If it is linearized, the update will not be used until a new build.
  • Empty functions will almost always be linearized. If you do not want this to happen for the previous reason use a noinline.
  • In C++ constructors and destructors will always have a code, even if it is empty.

The attribute noinline is usually used to "prevent" the compiler from linearizing the function. Each compiler has its own way of using this non-standard attribute. Obviously each compiler can use the rule they want to choose to do or not.

There is a way to ensure that the function will not be linearized, but this generates an additional cost in its use by causing a indirect extra:

void (*pFunc)() = func; //func é uma função definida em algum lugar
//a chamada
pFunc();

I put in the Github for future reference.

In recursive functions the attribute can even make the optimization transform a function into a constant value.

To help understand how the compiler works, check what it did in each case using the attribute inline.

Interesting article on the subject.

See also: About __forceinline and __inline.

3

The response of Maniero is, as always, excellent, but there is another semantic aspect of using inline which is less known.

The attribute inline causes a relaxation of the restrictions imposed by the "Single Definition Rule" (One Definiton Rule). According to the standard:

6 Basics

6.2 One-Definition Rule

10   Every program Shall contain Exactly one Definition of Every non-inline Function or variable that is odr-used in that program Outside of a discarded statement; in Diagnostic required. The Definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]). An inline Function or variable Shall be defined in Every Translation Unit in which it is odr-used Outside of a discarded statement.

(My emphasis)

This means that instead of requiring the function to be defined in only one translation unit, compiler will define the function with inline in each translation unit with the same definition.

As an example, assume we have three files:

Nop. h

void nop(){}

a. cpp

#include "nop.h"
int main(){}

b. cpp

#include "nop.h"

Compile using the command g++ a.cpp b.cpp generates the following error:

(...): In function `nop()':
b.cpp:(...): multiple definition of `nop()'
(...):a.cpp:(...): first defined here
collect2: error: ld returned 1 exit status

Normally, the fix would be to create a fourth file Nop.cpp, and adjust the file Nop. h to contain only one declaration:

Nop. h

void nop(); // Apenas uma declaração

Nop.cpp

#include "nop.h"
void nop(){} // Definição

The other way, of course, is simply to transform the function nop in a function inline:

Nop. h

inline void nop(){}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.