Explain the use of inline in C++

  • 2020-05-30 20:51:39
  • OfStack

1. Reasons for introducing the inline keyword

In c/c++, the inline modifier, which is represented as an inline function, was specifically introduced to solve the problem that some small functions that are frequently called consume a lot of stack space (stack memory).

Stack space refers to the memory space in which the local data of the program (that is, the data in the function) is placed.

In the system, the stack space is limited, if the frequent use of a large number of stack space will cause problems due to insufficient stack space and lead to errors in the program, for example, the final result of the function loop recursive calls is that the stack memory space is exhausted.

Here's an example:


#include <stdio.h>
// The function is defined as inline namely : Inline function 
inline char* dbtest(int a) {
  return (i % 2 > 0) ? " p. " : " accidentally ";
} 
int main()
{
  int i = 0;
  for (i=1; i < 100; i++) {
    printf("i:%d   parity :%s /n", i, dbtest(i));  
  }
}

The above example is the use of standard inline functions. The benefits of using inline modifications are not apparent on the surface, but what works internally is that within each for loop anywhere dbtest(i) is called instead (i%2) > 0) & # 63;" "Odd" : "even", so as to avoid frequent calls to the stack memory repeatedly open up the consumption of.

2. Restrictions on the use of inline

The use of inline is limited. inline is only suitable for the use of simple culvert Numbers in culvert bodies. It cannot contain complex structure control statements such as while and switch, and it cannot inline functions that are directly recursive (i.e., call their own functions internally).

3. inline is just one recommendation for the compiler

The inline function is just a suggestion to the compiler, so in the end, whether it's actually inlined or not depends on what the compiler means. If it thinks that the function is not complicated and can be expanded at the call point, it's actually inlined. It doesn't mean it's inlined if it's declared inlined, it's just a suggestion to declare inlined.

4. Recommendation: the definition of the inline function is in the header file

Second, because the inlined function is expanded at the call point, the compiler must have the inlined function definition everywhere, or else it will be a call to a non-inlined function. Therefore, this requires the definition of the inlined function to appear in every file that calls the inlined function.

Therefore, it is appropriate to implement the inline function definition in the header file, saving you the trouble of implementing it once per file.

If the inline function is implemented once per file, it is best to make sure that each definition is one, otherwise it will cause undefined behavior. If the definition is not the same in every file, which one the compiler expands depends on the specific compiler. Therefore, it is best to keep inline function definitions in a header file.

5. Class member functions and inline

Member functions defined in a class are by default inline, and it would be best if the function definition is given within the class at the time of class definition. If a member function is not defined in a class and you want to inline it, then inline must be added to the outside of the class, otherwise it is not considered inline.

For example,


class A
{
  public:void Foo(int x, int y) { } //  Automatically becomes an inline function 
}

Putting the body of the definition of a member function in a class declaration is not a good programming style, although it is convenient to write it. The example above should be:


//  The header file 
class A
{
  public:
  void Foo(int x, int y);
}
//  The definition file 
inline void A::Foo(int x, int y){} 

6. inline is a "keyword for implementation"

The keyword inline must be placed at 1 with the body of the function definition to make the function inline, and inline in front of the function declaration does nothing.

Functions Foo cannot be inline in the following style:


inline void Foo(int x, int y); // inline  Place only with function declarations 1 since 
void Foo(int x, int y){} 

The following style of function Foo becomes inline:


void Foo(int x, int y);
inline void Foo(int x, int y) {} // inline  And the body of the function definition 1 since 

So, inline is a "keyword for implementation", not a "keyword for declaration". As such, the user can read the declaration of the function, but not the definition of the function. Although in most textbooks the inline keyword is added before the declaration and definition body of inline functions, I don't think inline should appear in the declaration of functions. Although this detail does not affect the function function, it embodies a basic principle of the high-quality C++/C programming style: declaration and definition cannot be mixed as 1, and the user does not need to know whether the function needs to be inline or not.

7. Careful inline

Inlining makes functions more efficient, so why not define all functions as inline? If all functions are inline, do you still need the keyword "inline"?

Inlining improves function execution at the expense of code bloat (replication) and simply eliminates the overhead of function calls.

If the time it takes to execute the code inside the function is more expensive than the function calls, the efficiency gains are small. On the other hand, every call to an inline function has to copy the code, which will increase the total code of the program and consume more memory space.

Inlining should not be used in the following situations:

(1) if the code inside the function is relatively long, the use of inlining will lead to high memory consumption.

(2) if there is a loop in the function body, the time to execute the code in the function body is more expensive than the function call. Class constructors and destructors can easily be misinterpreted as being more efficient with inlining. Be aware that constructors and destructors may hide some behavior, such as "sneaking" the constructor and destructor of a base class or member object. So don't just throw the body of a constructor or destructor into a class declaration. A good compiler will automatically uninline undesirable functions based on the body of the function definition (this step further indicates that inline should not appear in the declaration of the function).

8. To summarize

Inline functions are not a magic bullet for performance enhancement. It's only when the function is very short that it gets the effect we want; However, if the function is not too short and is called in many places, it will increase the size of the executable.

The most annoying part is when the compiler rejects inlining. In the old implementation, the results were disappointing, and while there was a lot of improvement in the new implementation, it was still less than perfect. Some compilers are smart enough to figure out which functions can be inlined and which can't, but most are not, so it's up to our experience. If inline functions don't improve performance, avoid them!

conclusion


Related articles: