2012-04-24 2 views
14

저는 사용자를위한 정적 라이브러리로 끝나고 내 벡터 수학 인터페이스의 인라인을 통해 이익을 얻고 싶은 작은 C 수학 라이브러리를 다시 작성하고 있습니다.정적 라이브러리를 올바르게 인라인하는 법

나는 다음과 같습니다

[mymath.h]

... 
... 
extern float clampf(float v, float min, float max); 
... 
... 

[mymath.c]

inline float clampf(float v, float min, float max) 
{ 
    if(v < min) v = min; 
    if(v > max) v = max; 

    return v; 
} 

내 라이브러리는 정적하고 난 단지에 갈거야 때문에 사용자에게 .h (및 .lib)을 제공하면 컴파일시 해당 프로그램에 clampf 함수가 인라인됩니까?

올바른 일을하고 있지만 extern.h에, .c에 인라인으로 선언하고 있습니까?

답변

16

거의 정확합니다. 당신은 실제로 그것을 거꾸로 가지고 있습니다. 인라인 함수의 경우 헤더 파일에 inline 정의를 넣고 C 파일에 extern 선언을 넣어야합니다.

// mymath.h 
inline float clampf(float v, float min, float max) 
{ 
    if(v < min) v = min; 
    if(v > max) v = max; 

    return v; 
} 

// mymath.c 
#include "mymath.h" 
extern float clampf(float v, float min, float max); 

당신은,이 컴파일러가 그렇게하도록 선택하는 경우 인라인 정의를 사용할 수 있도록 헤더 파일을 포함하는 파일을 수 있도록 헤더 파일의 정의 (전신)을 넣어해야합니다.

컴파일러가 라이브러리에서 함수의 extern 버전을 내보내도록하려면 extern 선언 (프로토 타입)을 소스 파일에 넣어야합니다. 이렇게하면 라이브러리에 비 인라인 버전 용으로 하나의 위치가 제공되므로 컴파일러는 함수를 인라인하거나 일반 버전을 사용할 수 있습니다.

일반적으로 C에 대한 지원이 매우 부족한 MSVC 컴파일러에서는이 기능이 제대로 작동하지 않을 수 있습니다 (C99는 거의 지원되지 않음). GCC의 경우 이전 버전에 대한 C99 지원을 활성화해야합니다. 최신 C 컴파일러는 기본적으로이 구문을 지원합니다.

대안 : 당신은 static inline 버전을 가지고 헤더를 변경할 수 있습니다

,

// mymath.h 
static inline float clampf(float v, float min, float max) 
{ 
    ... 
} 

그러나,이 함수의 인라인이 아닌 버전을 제공하지 않기 때문에 컴파일러는 할 수있다 각 번역 단위에 대해이 기능의 사본을 만들어야합니다.

주 :

  1. C99 인라인 규칙은 정확하게 직관적 없습니다. "Inline functions in C"(mirror) 문서에서 자세히 설명합니다. 특히 맨 아래로 건너 뛰고 "인라인 함수 사용 전략"을 살펴보십시오. 나는 GCC가 C99 방식을 잠시 동안 기본값으로 사용하고 있기 때문에 방법 # 3을 선호합니다.

  2. 기술적으로는 extern이 기본값이므로 extern을 함수 선언 (또는 정의)에 넣을 필요가 없습니다. 나는 그것을 강조하기 위해 거기에 두었다.

+1

나는 당신의 대답이 틀렸다는 것을 확신합니다. 'inline' 함수가 아닌'static inline' 함수를 정의하면 함수가 여러 컴파일 단위로 사용되면 연결이 실패합니다. GCC 4.6 및 -std = c99로 테스트되었습니다. 함수 정의'extern inline'을 선언해도 작동하지만 GCC 확장입니다. – kay

+3

@kay : 전체 답변을 읽어보십시오. 번역 단위의 함수에 대한 'extern'선언을 어딘가에 추가해야합니다 (예 : 헤더가 아님). 그러면 해당 모듈에서 비 인라인 버전이 생성됩니다. C99 표준을 보거나 http://www.greenend.org.uk/rjk/tech/inline.html을 읽으십시오. –

+0

저는 확신합니다 :-) – kay

5

당신은 .H 파일에 static inline 같은 함수를 정의해야합니다

static inline float clampf(float v, float min, float max) 
{ 
    if(v < min) v = min; 
    if(v > max) v = max; 

    return v; 
} 

기능은 .c 파일에 존재해야합니다.

컴파일러는 함수를 인라인하지 않고 적절한 함수 호출로 만들 수 있습니다. 따라서 생성 된 모든 .o 파일에는 함수 복사본이 포함될 수 있습니다.

+2

정확하게 기억한다면 링커는 '정적 인라인'기능의 여러 복사본을 병합하지 않습니다. 따라서'inline' /'extern' 버전에 비해 중복 된 코드로 끝날 것입니다. (필연적 인 링커는 필연적으로 중복을 제거 할 수 있지만 일반적인 용도로는 사용할 수 없습니다.) –

+3

함수가 인라인이면 함수를 호출 할 때마다 코드가 복제됩니다. 이것은 의도적으로 설계된 것입니까? –

+0

@DietrichEpp 당신 말이 맞아요. 나는 (거짓으로)이 중복 코드 제거가 아직 표준이라고 생각했습니다. – kay

관련 문제