Moving inline methods from a header file to .cpp files

I have the following class defined in the header file foo.h

 class Foo { public: inline int Method(); }; inline int Foo::Method() { // Implementation } 

Now I would like to move the implementation to the foo.cpp file. To do this, I need to remove the inline and move the method implementation to a foo.cpp file like this

 #include `foo.h` inline int Foo::Method() { // Implementation } 

I have two questions:

  • Is my statement about removing the inline correct? Should it be necessarily deleted?
  • How does deleting the inline keyword usually affect performance (almost all of my methods are built-in)?

Thank you in advance.

+3
source share
6 answers

If you moved the function definition from the header to the cpp file, you MUST delete the inline all all locations for this function. With older linkers, this can make things a little slower, but with modern linkers you will not notice any real difference in performance. *

There are certain cases where the public member function may be inline , but this is just a bad idea. Do not do this. Arguments can be made to designate certain private member functions as inline , but in fact you really want those that are __attribute__((always_inline)) or __forceinline

* In extremely rare cases, this will make a difference, but in 99% of cases it will not, and 99.9% of what is left of you does not care. If the measurements show that you hit one to ten thousand, you can use the above __forceinline .

+12
source

The inline is redundant in the class. This is implied if you have a function body.

In the implementation file, it is also quite redundant.

Its only use is to define a free function in the header (or a member function outside the class, but in the header) to avoid multiple bodies.

Optimization on modern modern fog compilers is even more redundant, they still insert anything, without any doubt, or ignore your keyword at their discretion.

Inline use should be consistent! From 7.1.2p4:

The built-in function must be defined in each translation unit in which it is used as odr, and must have exactly the same definition in each case (3.2). [Note: a call to a built-in function can be met before its definition appears in the translation block. -end note] If a function definition appears in the translation block before its first declaration as inline, the program is poorly formed. If a function with an external link is declared inline in one translation unit, it must be declared embedded in all translation units in which it appears; diagnostics are not required ....

+5
source

If the function is not TINY (or takes a few arguments, but does not do much, for example, a constructor or similar, which takes a bunch of things and just copies it somewhere inside the class), inserting it will have little effect on performance in the first place. Setters and recipients are usually good candidates for inline, as they (usually) just copy data from one place to another and can easily be executed where the call is.

As others have said, this is a “compiler”, if I can ask you kindly, consider turning on this function “- this does not“ make this function inline. ”On the other hand, the compiler often performs inline functions regardless of whether inline : It looks at the size of the function, the number of calls, and the degree of increase in code from the attachment.

If you move the function to "foo.cpp", it will ONLY be embedded inside the compilation block "foo.cpp" (usually, compile unit = source file).

That is, if you don’t have a compiler capable of “optimizing the whole program” or similar tricks and enabling this function - this basically means that instead of preparing a link to an object file with machine code, the compiler creates an “analyzed but not fully translated into machine instructions "object file. Then, when it comes to the final installation of an executable (or shared library) toegether, the compiler / linker outputs one large piece of machine code from the halfway code. Both MS and GCC support this, but I don’t know how well it works for large projects.

Edit:

According to Mooing Duck's comment: the inline function does not create a real function name in the object file, so the linker may also give errors for unresolved symbol int Foo::Method() [or some wording to this extent].

Complete editing.

If performance is critical, you should measure the current code performance, then make changes and measure again. If this is significantly different, you will receive a response. If this is faster (due to less inlay leading to more cache bits for other bits of code, for example), then this is good. If it is slower, you will have to defer (some of) the functions to the header file. Or live with it slower ... Or find another way to make it faster ... The choice is yours (and if you work in a group, some other people may have a say in the final decision, of course). It is almost impossible for anyone to tell SURE how he will go, at least not understand the whole architecture of the programs and what happens in the class - that, given the name "foo.cpp" in the message, it is probably not REAL code ...

+4
source

You, and the people here who give tips on small features, are looking at the inline old-fashioned way.

inline means "I want this code to work fast, so whenever I call this function, I want you to extend it in place to avoid the overhead of calling the function."

This is a really good optimization. Actually, it’s so good that the compiler will look forward to doing this even if you do not specify inline .

The compiler also cannot extend your inline functions. Therefore, you really do not need to worry about how this will affect performance, because the compiler can and will ignore inline if you use it stupidly.

In fact, compilers today almost always ignore your use of inline and just do whatever they think is best.

So, knowing why people still use inline ?

Currently, there is only one reason to use inline , and also to work with the Unified Definition Rule (ODR).

In C / C ++, you can only define a function once. If you do this:

 int foo() { /* do something */ } int foo() { /* do something else */ } 

the compiler will complain that you have defined the same function twice.

This looks like a silly example, but it’s especially convenient to do something like this when you use #include - if you defined your function in the header and you #include the same header twice, that’s exactly what you are doing.

Fortunately, inline has another application that is still valid today: if you mark the function as inline , this forces the compiler to disable ODR problems, which allows you to define your function in the header.

In other words, inline now means "I want to define this function in the header."

When you look at this, it should be clear that you must remove inline when moving the function to the cpp file.


For fun, there are a couple of places where functions are implicitly made inline. One of them is included in the class functions:

 struct Foo { void bar() { /* do something */ } }; 

I have seen people mention features like inline , but this is completely redundant. The compiler does it anyway; There is no need to worry about ODR, and there is no performance you can get.

Another place in the templates. Because templates must be defined in headers, they are exempt from ODR, and inline they are redundant.

+3
source

This may be confusing, but you should not think about the purpose of inline to make the compiler inline in the function. (Modern compilers are smarter than you when a function needs to be inline or not).

No, the real purpose of inline is to tell the linker not to worry about multiple function definitions. If you put a function (non-member) definition in the header, you must mark it inline to avoid linker errors.

+1
source

2. How typically the removal of the inline keyword affect the performance (practically all my methods are inlined)?

The inline tells the compiler to take the implementation code for this function and place it instead of calling the function. This reduces the number of function calls on the stack and, if used correctly, can improve the performance of your program.

The inline should only be used with small features. Good examples are the Get and Set functions. They set the value of a single variable or return the value of a single variable.

If you create a function with a lot of inline code, it can significantly increase the size of your code (depending on the size of the function code and how many times this function is used) and actually DECREASE the performance of your program.

0
source

Source: https://habr.com/ru/post/989907/


All Articles