2012-11-20 3 views
1

헤더 전용 라이브러리를 작성 중이므로 사용자에게 제공하는 기능을 선언하는 사이에 마음을 굳힐 수는 없습니다 static 또는 inline. 이 경우에 내가 다른 것을 하나씩 선호해야하는 이유가 있습니까?정적 또는 인라인을 사용해야합니까?

+0

두 가지 목적을 수행합니다. 차이점은'static' 변수가 함수 내부에서 선언 될 때입니다. 'inline' 함수는 모든 파일에 대해 해당 변수의 복사본을 하나만 생성합니다. 그러나'static' 함수는 파일 당 복사본 하나를 생성합니다. – iammilind

+0

** 모두 C 및 C++ **로 잘 작동하는 코드를 작성하고 있습니까? 언어의 규칙은 다릅니다. –

+0

@ Cheersandhth.-Alf C++,하지만 두 경우 모두에 관심이 있습니다. – qdii

답변

6

그들은 모두 서로 다른 기능을 제공합니다.

inline 키워드를 사용하는 두 가지 의미가있다 (§ 7.1.3/4) :

  1. 호출의 시점에서 함수 본문의 대체가 일반적인 기능을 통해 바람직하다 컴파일러 힌트 이 호출 메커니즘.
  2. 인라인 대체를 생략해도 인라인에 대한 다른 규칙 (특히 1 정의 규칙)을 준수합니다.

함수에 static 키워드 내부 링키지 (인라인 기능은 외부 링크가)와 같은 기능의 각 인스턴스는 별도의 함수로 처리된다 갖도록 inline 함수를 강제 (각 기능 주소가 다르다) 및 이러한 기능의 각 인스턴스가 자신의 정적 지역 변수의 복사본 & 문자열 리터럴이 (인라인 함수는이 답변은 C99 규칙을 기반으로 이러한)

+0

C++ 11에서는 사실입니까? – qdii

+0

@qdii : 가능합니다. –

+2

+1 @qdii : 각 정적 변수에는 정적 변수, 리터럴 등이있을뿐만 아니라 코드가 복제되고 (인라인되지 않은 경우) 코드가 팽창 할 것이라는 점을 강조하는 것이 중요 할 수도 있습니다 바이너리와 성능에 영향을 미침 (명령어 캐시에 적합하지 않음) –

3

staticinline은 직교한다. 다른 말로하면, 둘 중 하나만 가질 수도 있고 둘 다 가질 수도 있습니다. 각각은 그것들을 사용할지를 결정하는 자체적 인 용도가 있습니다.

+0

헤더 전용 라이브러리에서는'none' 옵션을 사용할 수 없다고 생각합니다. 또한, OP는 언제 사용할지 묻습니다. 이 대답은 불완전합니다. 불행히도 내 +1이 잠겼습니다. 당신은 대답이 아닌 프로필 그림을 위해 그것을 고려할 수 있습니다. : | – iammilind

+0

@ iammilind 질문은 둘 사이에서 선택하는 것에 대해 묻습니다. 내 대답은 당신이 그들 사이에서 선택할 필요가 없다는 것을 설명하려고 시도하고 있습니다. 둘 또는 둘 다 사용할 수 있습니다. 또한, OP는 그가 헤더 파일에 대해서만 이야기하고 있다고 명시하지 않습니다. –

+0

효과는 직각입니다. 사실입니다. 여전히 실용적인 용도로는 연결이 있기 때문에 완전히 편집되지 않는 편집 작업은 함수의 집합에 대해'정적'→'인라인'을 변경하는 것입니다. 즉 네임 스페이스 범위와 클래스 범위 사이에서 함수를 이동할 때. –

1

해당 함수가 클래스 상태를 공유하지 않는 경우 : static. 함수를 만들려면 static 어디서든 호출하는 것이 좋습니다. 함수가 상대적으로 작고 깨끗하면

는 : inline

+0

+1 어드레싱 멤버 함수. '정적'은 비 멤버 함수에 대해 다른 의미를가집니다. –

+0

'함수가 상대적으로 작고 명확하면 : 인라인'은 매크로 스타일 인라이닝을 자체 방식으로 결정하는 최신 컴파일러에서는 문제가되지 않습니다. – iammilind

1

의 복사본 하나를 (이, 당신의 질문은 태그가 위 당신이 함수를 선언하면 C 및 C++, 그리고 C++의 규칙을 모두 잘

)과 다를 수 있습니다 토륨은 같은 단지 inline, 다음 함수의 정의는 인라인 정의입니다. 컴파일러는 번역 단위에서 함수에 대한 모든 호출에 인라인 정의를 사용할 필요가 없습니다. 다른 번역 단위에서 제공되는 동일한 함수의 외부 정의가 있다고 가정하고 일부 또는 모든 호출에이 함수를 사용할 수 있습니다 . 헤더 전용 라이브러리의 경우 이 아니며은 그러한 외부 정의이므로 링크 정의시 누락 된 정의가있는 프로그램을 사용하는 프로그램이 실패 할 수 있습니다.

한편, 함수를 모두 inlinestatic으로 선언 할 수 있습니다. 이 경우 컴파일러는 번역 단위의 함수에 대한 모든 호출에 대해 사용자가 제공 한 정의를 사용해야합니다. 실제로 해당 함수가 인라인되었는지 여부는 관계 없습니다. 이는 컴파일러가 inline static으로 선언 된 함수에 대해 정확히 동일하게 동작 할 가능성이 있지만 (실제로는 컴파일러가 static이라고 선언 된 경우에만 가능), 두 경우 모두 인라인으로 유용하다고 느끼기 때문에 실제로는 실제로 static 이상에서만 얻음).

+0

C++의 규칙은 실제로 다릅니다. C++에서'inline' 함수는 기본적으로 외부 링키지를 가지고 있으며, 내부 링키지를 사용하는 것에 대한 제한은 없습니다. C++에서 헤더 전용 코드의 기본 사용법은 암묵적인 외부 연결과 함께 단지'inline'입니다. –

+0

@ Cheersandhth.-Alf : C에서도'인라인 (inline) '함수는 기본적으로 외부 * 링키지 *를 가지고 있지만 반드시 외부 * 정의 *를 제공하지는 않습니다. OP가 자신의 헤더 전용 라이브러리를 C와 C++ 모두에서 사용할 수 있기를 원하는 경우에는 C에서 '정적'을 사용하기 위해 조건부 합병을 사용해야합니다. – caf

3

참고 :이 답변은 C++ 용입니다.C의 경우 caf's answer을 참조하십시오. 두 언어가 다릅니다. static 실용적인 관점에서 이름 링커에 보이지 않는 것을 의미 기능 내부 링크을 준다 공간 범위에서 함수의

  • :

    static 두 중요한 의미를 갖는다. static도이 방법으로 데이터에 사용할 수 있지만 데이터의 경우이 용도는 C++ 03 (C++ 03 Annex D의 § D.2, 규범 적)에서 더 이상 사용되지 않습니다. 여전히 상수는 기본적으로 내부 연결을 가지고 있습니다 (데이터 사용이 더 이상 사용되지 않으므로이를 명시 적으로 만드는 것이 좋지 않습니다). 함수 클래스의 객체없이 호출 될 수 있도록 클래스 함수의

  • static는 암시 this 인자를 제거한다. 하나는 함수가 헤더가 포함 된 모든 컴파일 단위에서 중복되고 싶지 않기 때문에 하나는 일반적으로 , 기능 내부 연결을 사용하지 않을 헤더에서

.

일반적인 규칙은 하나가 아닌 공용 모듈 인터페이스의 일부가 아닌 클래스 또는 함수를 필요로하고, 오염을 일반 네임 스페이스를 감소하고자 할 때, detail라는 중첩 된 네임 스페이스를 사용하는 것입니다 (즉, 가능성을 줄이기 이름 충돌). 이 규칙은 Boost 라이브러리에서 사용됩니다. include guard 기호와 같은 방식으로이 규칙은 현재 C++에서 모듈 지원이 부족하다는 것을 의미합니다.이 규칙은 본질적으로 규칙을 통해 몇 가지 중요한 언어 기능을 시뮬레이션하는 것으로 축소됩니다.

단어 inline 또한 두 중요한 의미를 갖는다 :

공간 범위에서 함수의
  • 이 함수의 정의 고의로 ’의 사용마다 컴파일 부에 제공되는 컴파일러에 지시를 . 실제로 이것은 링커가 함수의 여러 정의를 무시하게하고 헤더 파일에 비 템플릿 함수를 정의 할 수있게합니다. 템플릿에는 데이터에 대한 inline 효과를 시뮬레이트하는 데 사용할 수 있지만 데이터에는 해당 언어 기능이 없습니다.

  • 은 또한, 불행하게도, 함수 호출 강한 힌트 바람직 머신 코드에 인라인 “ ” 확장되어야 컴파일러를 준다.

첫 번째 의미는 inline의 유일한 보장 된 의미입니다.

일반적으로 헤더 파일의 모든 함수 정의에 inline을 적용하십시오. 한 가지 예외가 있습니다. 즉, 클래스 정의에 직접 정의 된 함수입니다. 이러한 함수는 자동으로 inline으로 선언됩니다 (즉, inline이라는 단어를 명시 적으로 추가하지 않고 링커 시위를 피할 수 있습니다. 따라서이 문맥에서 한 가지 실용적인 사용법은 클래스의 함수 선언에 inline을 적용하여 독자에게 함수는 헤더 파일의 뒷부분에 있습니다).

따라서 staticinline –의 의미에 대해 다소 혼란스러워 보이지만 상호 교환 가능하지 않습니다. – 본질적으로 오른쪽은 staticinline이 어떻게 든 연결되어 있습니다. 클래스에서 (무료) 함수를 네임 스페이스 범위로 이동하면 staticinline을 변경하고 네임 스페이스 범위에서 클래스로 함수를 이동하면 inlinestatic이 변경됩니다. 공통적 인 일은 ’이지만, 헤더 만의 코드를 리팩토링 할 때는 드문 일이 아닙니다.

합산 : 헤더에 정의 된 모든 네임 스페이스 범위 기능

  • 사용 inline. 특히, 기능 템플리트의 전문화에는 inline을 사용하십시오. 기능 템플리트는 완전히 전문화 될 수 있고 전체 전문화는 일반 기능이기 때.입니다. inline을 헤더 파일의 함수 템플리트 전문화에 적용하지 않으면 일반적으로 링크 오류가 발생합니다.

  • 특수 중첩 네임 스페이스를 사용하십시오. 내부 구현 세부 이름으로 인한 오염을 방지하기 위해 detail이라고합니다.

  • 정적 클래스 멤버의 경우 static을 사용하십시오.

  • static의 사용은 C++ 03에서 더 이상 사용되지 않으므로 (심지어 C++ 11에서 비추천이 제거 되었음에도 불구하고) 상수에 내부 연결이 있음을 명시하지 마십시오.

  • 데이터에 inline을 입력하면 ’을 적용 할 수 있지만 템플릿을 사용하여 거의 동일한 효과를 얻을 수 있습니다. 그러나 헤더에 구현 된 공유 상수 데이터의 큰 덩어리가 필요한 경우 inline 함수를 통해 데이터에 대한 참조를 생성하는 것이 좋습니다. 코드은 코드 작성이 훨씬 쉬우 며 코드 판독기에 대해 이해하기가 훨씬 쉽습니다. :-)

관련 문제