programing

여전히 인라인 용도가 있습니까?

nasanasas 2020. 9. 19. 11:24
반응형

여전히 인라인 용도가 있습니까? [복제]


이 질문에 이미 답변이 있습니다.

나는 여기서inline 읽었 기 때문에 쓸모가 없다고 믿었습니다 .

함수를로 지정하는 방법에 관계없이 inline컴파일러가 무시하도록 허용하는 요청입니다. 컴파일러는로 지정된 함수를 호출하는 위치의 일부, 전부를 인라인 확장하거나 전혀 확장하지 않을 수 있습니다 inline.

그러나 Angew 는 내가 모르는 것을 이해하는 것 같습니다. 에서 이 질문 여부가에 그와 나는 앞뒤로 꽤 갈 inline여전히 유용하다.

이 질문은 다음에 대한 질문이 아닙니다 .

컴파일러는 inline마음대로 할 수 있으므로 inline도움이되지 않습니다. 컴파일 된 코드의 변경을 제안 하는 것이 아니라 강제하는 데 사용할 inline있는 곳은 어디 입니까?


나는 나의 "비밀 이해"를 내가 할 수있는 최선의 방법으로 설명하려고 노력할 것이다.

여기에는 완전히 별개의 두 가지 개념이 있습니다. 하나는 호출 사이트에서 직접 함수 본문을 반복하여 함수 호출을 대체하는 컴파일러의 기능입니다. 다른 하나는 둘 이상의 번역 단위 (= 둘 이상의 .cpp파일) 에서 함수를 정의 할 수있는 가능성입니다 .

첫 번째는 함수 인라인이라고합니다. 두 번째는 inline키워드 의 목적입니다 . 역사적으로,inline 키워드는 또한 표시된 함수를 인라인 것을 컴파일러에 강한 제안했다 inline. 컴파일러가 최적화에있어 더 나아지면서이 기능은 줄어들었고 함수 inline를 인라인하기위한 제안으로 사용 하는 것은 실제로 쓸모가 없습니다. 컴파일러는 기꺼이 그것을 무시하고 더 나은 최적화라고 판단되면 완전히 다른 것을 인라인합니다.

나는 우리가 명시 적 inline인라인 관계를 다루었 기를 바랍니다 . 현재 코드에는 없습니다.

그렇다면 inline키워드 의 실제 목적은 무엇입니까? 간단합니다. 표시된 기능은 inlineODR (One Definition Rule)을 위반하지 않고 둘 이상의 번역 단위에서 정의 할 수 있습니다. 다음 두 파일을 상상해보십시오.

file1.cpp

int f() { return 42; }

int main()
{ return f(); }

file2.cpp

int f() { return 42; }

이 명령 :

> gcc file1.cpp file2.cpp

링커 오류가 발생하여 심볼 f이 두 번 정의 되었다고 불평합니다 .

당신이 가진 기능을 표시 할 경우, inline키워드, 그것은 특히 컴파일러 및 링커를 알려줍니다 : "너희들은 반드시이 함수의 여러 개의 동일한 정의가 않음을 확인 하지 오류가 발생할!"

따라서 다음이 작동합니다.

file1.cpp

inline int f() { return 42; }

int main()
{ return f(); }

file2.cpp

inline int f() { return 42; }

이 두 파일을 함께 컴파일하고 링크해도 링커 오류가 발생하지 않습니다.

Notice that of course the definition of f doesn't have to be in the files verbatim. It can come from an #included header file instead:

f.hpp

inline int f() { return 42; }

file1.cpp

#include "f.hpp"

int main()
{ return f(); }

file2.cpp

#include "f.hpp"

Basically, to be able to write a function definition into a header file, you have to mark it as inline, otherwise it will lead to multiple definition errors.


The last piece of the puzzle is: why is the keyword actually spelled inline when it has nothing to do with inlining? The reason is simple: to inline a function (that is, to replace a call to it by repeating its body on the call site), the compiler must have the function's body in the first place.

C++ follows a separate compilation model, where the compiler doesn't have access to object files other than the one it's currently producing. Therefore, to be able to inline a function, its definition must be part of the current translation unit. If you want to be able to inline it in more than one translation unit, its definition has to be in all of them. Normally, this would lead to a multiple definition error. So if you put your function in a header and #include its definition everywhere to enable its inlining everywhere, you have to mark it as inline to prevent multiple definition errors.

Notice that even today, while a compiler will inline any function is sees fit, it must still have access to that function's definition. So while the inline keyword is not required as the hint "please inline this," you may still find you need to use it to enable the compiler to do the inlining if it chooses to do so. Without it, you might not be able to get the definition into the translation unit, and without the definition, the compiler simply cannot inline the function.

The compiler cannot. The linker can. Modern optimisation techniques include Link-Time Code Generation (a.k.a. Whole Program Optimisation), where the optimiser is run over all object files as part of the linking process, before the actual linking. In this step, all function definitions are of course available and inlining is perfectly possible without a single inline keyword being used anywhere in the program. But this optimisation is generally costly in build time, especially for large projects. With this in mind, relying solely on LTCG for inlining may not be the best option.


For completeness: I've cheated slightly in the first part. The ODR property is actually not a property of the inline keyword, but of inline functions (which is a term of the language). The rules for inline functions are:

  • Can be defined in multiple translation units without causing linker errors
  • Must be defined in every translation unit in which it is used
  • All its definitions must be token-for-token and entity-for-entity identical

The inline keyword turns a function into an inline function. Another way to mark a function as inline is to define (not just declare) it directly in a class definition. Such a function is inline automatically, even without the inline keyword.


inline is mostly just an external linkage specifier now, for the reasons you stated.

So yes, it does have a use, but it's a different one than actually inlining functions. It allows you to define the same method multiple times between compilation units and properly link them together, instead of getting multiple definition errors.

//header.h
inline void foo() {}
void goo() {}

//cpp1.cpp
#include "header.h"

//cpp2.cpp
#include "header.h"

// foo is okay, goo breaks the one definition rule (ODR)

Actually forcing function inlining is up to the compiler, some might have support via specific attributes or pragmas or (__forceinline) or whatnot.

Simply put, it allows you to define functions in headers without breaking the ODR...

참고URL : https://stackoverflow.com/questions/29796264/is-there-still-a-use-for-inline

반응형