반응형
해당 글은 아래의 공식문서를 요약한 글입니다.
틀린 부분이 있으면 알려주세요!
https://learn.microsoft.com/ko-kr/cpp/cpp/inline-functions-cpp?view=msvc-170
Inline 함수란?
- 컴파일러가 해당 함수에 대한 각 호출 대신 함수 정의 내의 코드를 대체하도록 제안합니다.
- 이론적으로 인라인 함수를 사용하면 함수 호출과 연관된 오버헤드가 제거되어 프로그램 속도가 더 빨라질 수 있습니다.
- 인라인 함수의 단점은 프로그램의 전체 크기가 증가할 수 있다는 것입니다.
- 인라인 코드 대체는 컴파일러의 재량에 따라 수행됩니다. 예를 들어 컴파일러는 함수 주소를 가져온 경우나 함수가 너무 크다고 판단하는 경우 함수를 인라인 처리하지 않습니다.
요약하자면
함수 내 코드를 호출쪽으로 끌고와 call 오버헤드를 줄여주는 기법이다.
썻을 때 성능이 좋아질 수 있고 메모리가 증가하며 Inline 함수는 적용이 안될 수도 있다.
Inline 함수로 적용 안되는 경우?
- 재귀 함수
- 변환 단위의 다른 위치에서 포인터를 통해 참조되는 함수
- 크기가 큰 함수
inline, __inline 및 __forceinline
- 키워드로 inline, __inline, __forceinline이 있다.
- inline과 __inline은 서로 동일하다.
- __forceinline은 컴파일러의 결정과 상관없이 강제로 inline함수로 변형시킨다.
#define vs inline 함수
- 서로의 목적과 기능은 완전히 동일하다.
- 매크로는 항상 인라인으로 확장되지만 인라인 함수는 컴파일러에 의해 최적이라고 판단될 때만 인라인 처리가 이루어진다.
- 매크로는 예기치 않은 동작을 발생시킬 수 있고, 이로 인해 미묘한 버그가 발생할 수 있습니다. 예를 들어 식 mult1(2 + 2, 3 + 3)이 11로 계산되는 2 + 2 * 3 + 3으로 확장되지만, 예상 결과는 24입니다. 유효해 보이는 수정 방법은 함수 매크로의 두 인수 주위에 괄호를 추가하여 #define mult2(a, b) (a) * (b)의 결과를 가져오는 것입니다. 이렇게 하면 당면 문제는 해결되지만, 더 큰 식의 일부인 경우에는 여전히 놀라운 동작이 발생할 수 있습니다. 이는 앞의 예에서 설명했으며, 매크로를 #define mult3(a, b) ((a) * (b))로 정의하여 문제가 해결될 수 있습니다.
- 인라인 함수는 컴파일러의 의미 체계 처리의 대상이 되지만, 전처리기는 이와 동일한 이점 없이 매크로를 확장합니다. 매크로는 형식이 안전하지 않지만 함수는 형식이 안전합니다.
- 인라인 함수에 인수로 전달된 식은 한 번 계산됩니다. 매크로에 인수로 전달된 식은 경우에 따라 여러 번 계산할 수 있습니다.
요약하자면
- inline 함수는 컴파일 단계에서 인수 에러를 잡아주지만 매크로는 그렇지 않다.
- 매크로는 항상 인라인으로 확장되지만 inline 은 컴파일러에 따라 다르다.
- 매크로는 경우에 따라 여러 번 계산하기에 예기치 않은 동작을 할 수 있다.
#define의 예기치 않은 동작을 한다는 코드의 예시
#include <iostream>
#define sqr(a) ((a) * (a))
int increment(int& number)
{
return number++;
}
inline int square(int a)
{
return a * a;
}
int main()
{
int c = 5;
std::cout << sqr(increment(c)) << std::endl; // outputs 30
std::cout << c << std::endl; // outputs 7
c = 5;
std::cout << square(increment(c)) << std::endl; // outputs 25
std::cout << c; // outputs 6
}
예상값으로는 increment로 증감 연산자 중 후위 연산자를 수행 후
반환값인 5의 제곱인 25를 출력하는게 맞지만
매크로 함수는 30을 출력합니다.
그 이유는
식 sqr(increment(c))가 ((increment(c)) * (increment(c)))로 확장할 때 함수 increment가 두 번 호출되기 때문입니다.
결론
- 매크로는 inline 함수보다 안전하지 않다.
- 매크로는 항상 inline 되지만 inline 함수는 컴파일러에 따라 다르다.
- inline을 강제하게 되었을 때 성능이 안좋아질 수 있다.
- inline 되면 프로그램 메모리가 증가한다.
반응형
'C++' 카테고리의 다른 글
[C++] Flatbuffer 사용법 (0) | 2024.11.13 |
---|---|
[C++] IOCP OverlappedEx 구조체에 관하여 (0) | 2024.10.21 |
[C++] find_if 로 특정 클래스 가져오기 (0) | 2024.07.13 |
[C++] String Compare vs strcmp (0) | 2023.07.22 |
[C++] Html Form 인코딩된 데이터 디코딩하기 (0) | 2023.07.05 |