답변:
inline
C 출신이고; C ++에는 처음이 아니 었습니다.
프로그래머가 코드 최적화를 지원할 수 있도록 설계된 C 키워드 ( register
및 inline
)가 있습니다. 컴파일러는 레지스터 할당에서 더 나은 기능을 수행하고 함수를 인라인 할시기를 결정할 수 있기 때문에 일반적으로 오늘날 무시됩니다 (사실 컴파일러는 다른 시간에 함수를 인라인하거나 인라인하지 않을 수 있음). 최신 프로세서의 코드 생성은 Ritchie가 C를 발명 할 때 일반적으로 사용되는 결정 론적 코드보다 훨씬 복잡합니다.
현재 C ++에서이 단어의 의미는 여러 개의 동일한 정의를 가질 수 있으며이를 사용하는 모든 번역 단위에서 정의되어야한다는 것입니다. (즉, 인라인 될 수 있는지 확인해야합니다.) inline
문제없이 헤더에 함수를 가질 수 있으며 클래스 정의에 정의 된 멤버 함수는 자동으로 효과적 inline
입니다.
inline
.
inline
그것이 C에서 공급 업체 확장으로 이미 사용 가능했지만 C ++로 먼저 표준화 되었다는 것을 확신합니다 ... 예, C99의 C 표준에 추가 된 것으로 보입니다.
inline
C99 이상의 규칙 inline
은 C ++ 의 규칙과 다릅니다 .
원래 inline
는 함수 호출이 인라인되어야한다는 매우 강력한 힌트였습니다.
그러나 유일하게 보장되는 효과 inline
는 함수를 여러 번역 단위로 정의 할 수 있도록하는 것입니다. 예를 들어, 정의를 헤더 파일에 배치하는 것입니다.
오늘날 일부 컴파일러는 g ++과 같은 인라인 힌트를 따르는 데 매우 관심이 있습니다. 그리고 일부 컴파일러는 Visual C ++와 같이 덜 심각합니다. 그러나 모두 보증을 준수해야합니다.
불행히도 최적화 힌트와 링커 레벨 폐기 가능 정의라고하는이 두 가지 의미는 동일한 키워드로 존재한다는 것은 불행히도 실제로는 다른 의미없이 하나를 가질 수 없기 때문입니다.
불행히도 inline
(또는 더 나은 경우, 폐기 가능한 정의에 대한 별도의 키워드) ¹ 데이터에 적용 할 수 없습니다 .
헤더 전용 모듈이 널리 보급됨에 따라 링커 레벨 폐기 가능 데이터의 필요성이 증가했습니다. 예를 들어, 많은 Boost 하위 라이브러리는 헤더 전용입니다.
그러나 데이터의 경우 템플릿을 사용하여 약간의 트릭을 적용 할 수 있습니다. 일부 클래스 템플릿에서 정의하고 typedef
템플릿 매개 변수 void
(또는 무엇이든)를 제공하십시오. 하나의 정의 규칙이 템플릿에 대해 특정 예외를 만들기 때문입니다.
참고 :
¹ inline
변수는 C ++ 17에서 지원됩니다 .
inline
.
기본적으로 모든 기능을 인라인으로 설정하지 않는 이유는 무엇입니까? 엔지니어링 트레이드 오프이기 때문입니다. "최적화"에는 최소한 두 가지 유형이 있습니다. 프로그램 속도를 높이고 프로그램의 크기 (메모리 공간)를 줄입니다. 인라인은 일반적으로 속도를 높입니다. 스택에서 매개 변수를 밀고 당기는 것을 피하면서 함수 호출 오버 헤드를 제거합니다. 그러나 모든 함수 호출은 이제 함수의 전체 코드로 대체되어야하기 때문에 프로그램의 메모리 풋 프린트가 더 커집니다. 보다 복잡한 작업을 수행하기 위해 CPU는 자주 사용되는 메모리 청크를 CPU의 캐시에 저장하여 매우 빠르게 액세스 할 수 있습니다. 프로그램의 메모리 이미지를 충분히 크게 만들면 프로그램에서 캐시를 효율적으로 사용할 수 없으며 최악의 경우 인라인으로 인해 실제로 프로그램 속도가 느려질 수 있습니다.
“인라인”을 이해하려면 역사와 20 년 전과 30 년 전의 삶 을 이해해야합니다.
메모리가 거의없는 컴퓨터에서 코드를 작성하고 있었기 때문에 컴파일러가 프로그램을 구성하는 모든 코드를 한 번에 처리 할 수 없었습니다. 컴파일러도 매우 느리기 때문에 변경되지 않은 코드를 다시 컴파일 할 필요가 없었습니다. 24 시간 이상 (최고급 자동차보다 비싼 컴퓨터에서) 모든 코드를 다시 컴파일하는 데 몇 가지 프로젝트가 정상이었습니다. 에서 일하는.
따라서 각 코드 파일은 개별적으로 오브젝트 파일로 컴파일되었습니다. 각 객체 파일은 함수의 "주소"와 함께 포함 된 모든 함수 목록으로 시작되었습니다. 또한 객체 파일에는 호출 위치와 함께 다른 객체 파일에서 호출 한 모든 함수 목록이 있습니다.
링커는 먼저에게 오브젝트 파일을 읽고, 그들은 그들이에 있던 파일이 주소와 함께 수출 모든 기능의 목록을 구축 할 것입니다. 그런 다음 모든 "외부"함수 호출을 함수 주소로 업데이트하면서 모든 객체 파일을 다시 읽고 프로그램 파일로 출력합니다.
링커는 외부 함수 호출에 대한 참조를 수정하는 것 이외의 다른 방법으로 컴파일러가 생성 한 기계어 코드를 변경하거나 최적화하지 않았습니다. 링커는 운영 체제의 일부였으며 대부분의 컴파일러보다 오래되었습니다. 사람들이 새 컴파일러를 작성할 때 현재 링커와 함께 작동하고 현재 객체 파일에 링크 할 수 있어야했습니다. 그렇지 않으면 시스템 호출을 할 수 없었습니다.
컴파일러는 포함 된 모든 헤더 파일과 함께 컴파일되는“.c”또는“.cpp”파일의 코드 만 보았습니다. 따라서 다른“.c”또는“.cpp”파일의 코드를 기반으로 최적화를 수행 할 수 없었습니다.
“inline”키워드를 사용하면 함수 본문 (메서드)을 헤더 파일에 정의 할 수 있으므로 컴파일러는이를 호출하는 코드를 컴파일하는 동안 함수 코드를 사용할 수 있습니다. 예를 들어 다른 .cpp 파일에 컬렉션 클래스가 정의되어 있다고 가정하면이 클래스에는 한 줄의 코드가 포함 된 "isEmpty"메서드가 있으며 함수를 호출하는 대신 결과 프로그램의 속도가 크게 향상됩니다 함수 호출이이 한 줄로 대체되었습니다.
"inline"키워드는 당시 많은 프로그래머가 객체의 개인 필드에 액세스하지 않고도 함수 호출 비용을 피하면서 데이터를 캡슐화 할 수있는 "싸고 쉬운"방법으로 여겨졌습니다. (당시에 일반적인 코드를 "인라이닝"하는 훨씬 나쁜 방법입니다.)
요즘“링커”는 많은 코드 최적화를 수행하며 일부 팀에서 컴파일러로 작성하는 경향이 있습니다. 컴파일러는 종종 코드가 올바른지 확인하고이를“압축”하여 대부분의 기계 코드 작성 작업을 링커에 남겨 둡니다.
표준의 내용 (굵게 강조 표시된 중요 부분)을 살펴 보겠습니다.
2. 인라인 지정자가있는 함수 선언은 인라인 함수를 선언합니다. 인라인 지정자는 호출 시점에서 함수 본문의 인라인 대체 가 일반적인 함수 호출 메커니즘 보다 선호 됨을 구현에 표시합니다 . 호출 시점 에서이 인라인 대체 를 수행하기 위해 구현이 필요하지 않습니다 . 그러나이 인라인 대체가 생략 되더라도 인라인 함수에 대한 다른 규칙은 여전히 준수해야합니다.
— C ++ 표준, ISO / IEC 14882 : 2003 , 7.1.2 함수 지정자 [dcl.fct.spec]
따라서 확실하게하려면 컴파일러 설명서를 읽어야합니다.
많은 머신 코드가 복제 될 수 있으므로 모든 것을 인라인하는 것은 나쁜 생각입니다 ...
따라서 다음을 알아야합니다.
간단한 대답은 없습니다 . 가장 좋은 것을 보려면 그것을 가지고 놀아야합니다. 마 하지 "결코 사용과 같은 단순한 답을 정착
inline
기능"또는 "항상 사용inline
기능"또는 "사용inline
기능이 적은 코드의 N 라인보다의 경우에만 작동합니다." 이러한 모든 규모에 맞는 규칙을 작성하기는 쉽지만 최적의 결과를 낼 수는 없습니다.— C ++ FAQ, 인라인 함수 , 9.3
inline
함수가 성능을 향상 시킵니까?
inline
OP가 부분을 놓친 것처럼 지식을 되풀이 하여 요점을 말하고 있습니다. 이것이 그가 요점을 얻지 못하는 핵심 이유입니다. 포인트를 얻으려면 그 포인트 아래에 무엇이 있는지 이해해야합니다.
인라인 키워드를 사용하는 좋은 이유를 알려 드리겠습니다.
티켓 프린터 또는 이와 유사한 소형 시스템과 같은 내장 시스템 프로세서는 매우 제한되어 있으며 함수 호출 (스택에서 함수 매개 변수 준비, 호출, 스택에서 매개 변수 가져 오기 및 답장 등)은 함수 자체 옆에서 실행하는 데 몇 ms가 걸릴 수 있습니다.
호출 시간은 약 60ms (실제 기능이 아닌 호출 전용)이고 50 회 반복합니다 (루프 또는 반복 호출 트리).
해당 함수 호출에서 앞뒤로 이동하는 데 60 * 50 = 3000 (3 초)이 걸립니다.
메모리가 있다면 확실히 3 초를 절약하기 위해 인라인을 수행 할 것입니다.
따라서 인라인은 기본적으로 실행 속도가 필요할 때 사용됩니다. 내가 참여한 일부 프로젝트에서 호출 시간은 실행 시간보다 길었습니다. 인라인을 사용할 때의 전형적인 상황입니다.