헤더에 C ++ 인라인 함수가있는 이유는 무엇입니까?
NB 이것은 인라인 함수를 사용하는 방법이나 작동 방식에 대한 질문이 아닙니다.
클래스 멤버 함수의 선언은 함수를로 정의 할 필요가 없으며 함수 inline
의 실제 구현 일뿐입니다. 예를 들어, 헤더 파일에서 :
struct foo{
void bar(); // no need to define this as inline
}
그렇다면 클래스 함수의 인라인 구현이 헤더 파일에 있어야 하는 이유는 무엇입니까? 인라인 기능을 .cpp
파일에 넣을 수없는 이유는 무엇 입니까? 인라인 정의를 .cpp
파일 에 넣으려고하면 다음 과 같은 오류가 발생합니다.
error LNK2019: unresolved external symbol
"public: void __thiscall foo::bar(void)"
(?bar@foo@@QAEXXZ) referenced in function _main
1>C:\Users\Me\Documents\Visual Studio 2012\Projects\inline\Debug\inline.exe
: fatal error LNK1120: 1 unresolved externals
inline
함수 의 정의는 헤더 파일에있을 필요는 없지만 인라인 함수에 대한 하나의 정의 규칙으로 인해 함수에 대한 동일한 정의가이를 사용하는 모든 번역 단위에 존재해야합니다.
이를 달성하는 가장 쉬운 방법은 헤더 파일에 정의를 넣는 것입니다.
단일 소스 파일에 함수 정의를 넣으려면 선언하면 안됩니다 inline
. 선언 inline
되지 않은 함수 는 컴파일러가 함수를 인라인 할 수 없음을 의미하지 않습니다.
함수를 선언해야하는지 여부 inline
는 일반적으로 하나의 정의 규칙 중 어떤 버전을 따라야 하는지를 기준으로 선택해야합니다 . 추가 inline
하고 후속 제약에 의해 제한되는 것은 거의 의미가 없습니다.
두 가지 방법으로 볼 수 있습니다.
함수 호출을 인라인하려면 컴파일러가 함수 본문을 볼 수 있어야하므로 인라인 함수는 헤더에 정의됩니다. 순진한 컴파일러가이를 수행하려면 함수 본문이 호출과 동일한 번역 단위에 있어야합니다. (최신 컴파일러는 번역 단위 전체에서 최적화 할 수 있으므로 함수 정의가 별도의 번역 단위에 있더라도 함수 호출이 인라인 될 수 있지만 이러한 최적화는 비용이 많이 들고 항상 활성화되지 않으며 항상 지원되지는 않았습니다. 컴파일러)
헤더에 정의 된 함수는 표시되어야합니다.
inline
그렇지 않으면 헤더를 포함하는 모든 번역 단위에 함수의 정의가 포함되고 링커는 여러 정의에 대해 불평 할 것입니다 (단일 정의 규칙 위반).inline
키워드는 여러 번역 단위 (동일) 정의를 포함 할 수 있도록이를 억제한다.
두 가지 설명은 inline
키워드가 예상 한대로 정확하게 작동하지 않는다는 사실로 귀결됩니다 .
C ++ 컴파일러는 프로그램의 관찰 가능한 동작을 변경하지 않는 한 언제든지 인라인 최적화 (함수 호출을 호출 된 함수의 본문으로 대체하여 호출 오버 헤드 절약 )를 자유롭게 적용 할 수 있습니다.
inline
키워드를 만들어 쉽게 함수 정의가 여러 번역 단위로 볼 수 있도록 허용하지만, 컴파일러를 의미하지 않는다 키워드를 사용하여,이 최적화를 적용 할 컴파일러 했다 함수를 인라인하고, 하지 않는 키워드를 사용하여 컴파일러가 함수를 인라인하는 것을 금지합니다.
이것은 C ++ 컴파일러의 한계입니다. 헤더에 함수를 넣으면 인라인 될 수있는 모든 cpp 파일이 함수의 "소스"를 볼 수 있으며 컴파일러에서 인라인을 수행 할 수 있습니다. 링커가 인라인을 수행해야하는 경우도 있습니다 (각 cpp 파일은 obj 파일에서 개별적으로 컴파일됩니다). 문제는 링커에서 수행하는 것이 훨씬 더 어려울 것이라는 것입니다. "템플릿"클래스 / 함수에도 유사한 문제가 있습니다. 링커가 인스턴스화 (특수 버전 생성)하는 데 문제가 있기 때문에 컴파일러에 의해 인스턴스화되어야합니다. 일부 최신 컴파일러 / 링커는 컴파일러가 첫 번째 단계를 수행하는 "2 단계"컴파일 / 링크를 수행 한 다음 링커가 작업을 수행하고 컴파일러를 호출하여 해결되지 않은 사항 (인라인 / 템플릿 ...)을 해결할 수 있습니다.
그 이유는 컴파일러가 호출 대신 정의 를 드롭 할 수 있도록 실제로 정의 를 확인해야하기 때문입니다.
C와 C ++는 컴파일러가 항상 한 번에 하나의 번역 단위 만 보는 매우 단순한 컴파일 모델을 사용합니다. (이는 수출에 실패하며 이는 단 하나의 공급 업체에서만 실제로 구현 한 주된 이유입니다.)
C ++ inline
키워드는 오해의 소지가 있으며 "이 함수를 인라인"한다는 의미는 아닙니다. 함수가 인라인으로 정의되면 모든 정의가 동일하면 여러 번 정의 할 수 있다는 의미입니다. inline
호출 된 지점에서 코드를 인라인하는 대신 호출되는 실제 함수로 표시된 함수는 완벽하게 합법적입니다 .
헤더 파일에 함수를 정의하는 것은 템플릿에 필요합니다. 예를 들어 템플릿 클래스는 실제로 클래스가 아니기 때문에 여러 변형을 만들 수있는 클래스 의 템플릿 입니다. 컴파일러가 예를 들어 Foo 템플릿을 사용하여 Foo 클래스를 만들 때Foo<int>::bar()
함수를 만들 수 있으 려면 의 실제 정의 Foo<T>::bar()
가 표시되어야합니다.
나는 이것이 오래된 스레드라는 것을 알고 있지만 extern
키워드를 언급해야한다고 생각했습니다 . 나는 최근 에이 문제를 만났고 다음과 같이 해결했습니다.
Helper.h
namespace DX
{
extern inline void ThrowIfFailed(HRESULT hr);
}
Helper.cpp
namespace DX
{
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
std::stringstream ss;
ss << "#" << hr;
throw std::exception(ss.str().c_str());
}
}
}
컴파일러는 그들을 인라인 하기 위해 그들을 볼 필요가 있기 때문 입니다. 헤더 파일은 다른 번역 단위에 일반적으로 포함되는 "구성 요소"입니다.
#include "file.h"
// Ok, now me (the compiler) can see the definition of that inline function.
// So I'm able to replace calls for the actual implementation.
인라인 함수
In C++ a macro is nothing but inline function. SO now macros are under control of compiler.
- Important : If we define a function inside class it will become Inline automatically
Code of Inline function is replaced at the place it is called, so it reduce the overhead of calling function.
In some cases Inlining of function can not work, Such as
If static variable used inside inline function.
If function is complicated.
If recursive call of function
If address of function taken implicitely or explicitely
Function defined outside class as below may become inline
inline int AddTwoVar(int x,int y); //This may not become inline
inline int AddTwoVar(int x,int y) { return x + y; } // This becomes inline
Function defined inside class also become inline
// Inline SpeedMeter functions
class SpeedMeter
{
int speed;
public:
int getSpeed() const { return speed; }
void setSpeed(int varSpeed) { speed = varSpeed; }
};
int main()
{
SpeedMeter objSM;
objSM.setSpeed(80);
int speedValue = A.getSpeed();
}
Here both getSpeed and setSpeed functions will become inline
참고URL : https://stackoverflow.com/questions/5057021/why-are-c-inline-functions-in-the-header
'Programing' 카테고리의 다른 글
SQL Server Management Studio에서는 테이블에 인덱스를 추가 할 수 없습니다. (0) | 2020.08.09 |
---|---|
마지막 git 커밋으로 롤백 (0) | 2020.08.09 |
AlertDialog 제목의 색상과 그 아래 줄의 색상을 어떻게 변경할 수 있습니까? (0) | 2020.08.09 |
Index Range Swift의 새로운 배열 (0) | 2020.08.09 |
Xcode 4에서 저작권 템플릿을 어떻게 변경할 수 있습니까? (0) | 2020.08.09 |