Attachment of this function or not?

I have to implement a function that compares two simliar lines so strcmp , but ignores whitespace, so

 strcmpignorews("abc ", " abc") 

should give the same result.

Here is my implementation:

 namespace { void SkipWhitespace(const char *&s) { for (; std::isspace(*s, std::locale::classic); ++s); } } int strcmpignorews(const char *s1, const char *s2) { for (; *s1 != '\0' && *s2 != '\0'; ++s1, ++s2) { SkipWhitespace(s1); SkipWhitespace(s2); if (*s1 != *s2) { break; } } return (*s1 < *s2) ? -1 : ((*s1 == *s2) ? 0 : 1); } 

Now, the question is, does it make sense to embed the SkipWhitespace function? I think I read somewhere that inline should not be used for functions that contain loops or switches, but I cannot remember where and why.

+4
source share
5 answers

Historically, Inline has indicated to the compiler that it should insert the function body into the call site. However, this is no longer a meaningful annotation. Modern compilers will embed the function or not, regardless of the presence or absence of inline qualifications.

To emphasize whether the compiler will perform inline optimizations completely out of your hands.

In modern use, the built-in function has only one function. It can be used to force the linker to ignore multiple characters, for example, when a function is defined in multiple compilation units. This method can be used to break circular dependencies. Use inline for other purposes.

+13
source

I would not say that it should not be used in these circumstances, but the effect of the inlay code will have a greater benefit if the code is relatively fast.

This is because inlining gets rid of the overhead of calling a function. If the function call and return takes one second, but the code you insert takes ten minutes, you will not see much improvement. But if the code you embed takes one second, you basically double its performance.

Just keep in mind that inline is a suggestion to the compiler that it can freely ignore if it finds out that you are wrong or even if it is just unpleasant. I rarely use it and rarely find a need for it, dropping it into the same category as auto and register (at least in C).

+3
source

The inline has always been a simple suggestion for the compiler. This means that if the compiler chooses this, it can ignore this sentence. In addition, if the compiler can inline a function, it can inline this function, even if you did not ask it to do so.

However, for the compiler to be able to inline the function, it must know the body of the function. If a function is defined in a separate compilation unit, then the compiler probably does not know the function definition outside this compilation unit. In this case, the compiler can only embed the function in callers in the compilation unit that defines the function. Therefore, you should take into account that if you want to allow the compiler to embed a function, you must define the function in the class definition or add the inline and define it in the header. Built-in functions do not violate ODR .

Another consideration you should make is that since inline functions should be in the header, and since headers are usually included with a number of compilation units, inline functions increase the static link. This means that changing the definition of an inline function will lead to a cascade in compilation through all dependent compilation units. This is important: defining a function does not have to be part of the interface, but built-in functions force this connection.

For this last point, in the end, I would say never a built-in function. That is, until you are annoyed enough by the speed of your application or library, at this point you should run the profiler to see if any specific functions will improve performance. Built-in functions can also reduce the size of the executable file if their attachment leads to a smaller object than the code needed to generate the function call, but this is a less important decision-making factor in most, but few (built-in?) Contexts.

The profiler can tell you that a particular function can improve performance if it is built-in, but it cannot tell you if a particular built-in function can improve performance (size, runtime, development, ...) if it is not enabled.

+3
source

In general, Profile before embedding .

Attachment is always a suggestion for the compiler. He reserves the right to ignore you or agree with you. In any case, it could be embedding other parts of your code without your permission.

If you don't mind extra printing, here are some guidelines for declaring a method or function as inline:

  • The content of the method uses less than or equal to instructions cycles for calling, initializing, clearing and returning from the Method.
  • The method has no transitions or branches to other methods.
  • The method has no loops (currently, small loops can fit into the processor cache).
  • The method uses only methods that are built-in or may include library functions.
  • You are converting a macro ( #define ).
  • The method passes the above tests (except 5), and fully tests. (You could say rebuild all the dependencies because you changed the title?)

My style is the built-in getters and seters class. Any code that is mutable (either does not work, or can be modified) or is complex will not be embedded.

+3
source

In the context there is no harm and, possibly, the benefit of using inline .

There are restrictions on the complexity of the function that the compiler will embed; functions with complex cycles or commutators are more likely to reach this limit than without functions. So, what you are reading is not all wrong; it just needs to be qualified.

Stylistically, I would use a while instead of your for loop:

 while (isspace(*s, std::locale::classic)) ++s; 

This also fixes a bug in your code that only allows characters that are not spaces. (Bug fixed when this answer was introduced!)

+2
source

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


All Articles