2009-10-14 5 views
4

헤더 라이브러리 (예 : Boost)를 작성할 때 (1) 생성 된 바이너리를 확장하지 않고 (2) 발생하지 않고 자유 플로팅 "사용하지 않은"경고?헤더 라이브러리에서 (비 메소드) 함수를 정의하는 방법

동일한 바이너리로 차례로 링크 된 여러 소스 파일에 포함 된 헤더에 함수를 정의하면 링커가 재정의에 대해 불평합니다. 이 문제를 해결하는 한 가지 방법은 함수를 정적으로 만드는 것입니다.하지만이 방법은 각 번역 단위에서 코드를 재생산합니다 (BTW, 링커는이 코드를 안전하게 복제 할 수 있습니까?). 또한, 사용되지 않는 함수에 대한 컴파일러 경고를 트리거합니다.

부스트에서 부동 함수의 예를 찾으려고했으나 찾을 수 없습니다. 클래스 (또는 템플릿)의 모든 것을 포함하는 트릭이 있습니까?

+0

왜 그런 식으로하고 싶습니까? – AnT

+0

* BTW는 링커가 안전하게 이들을 복제 할 수 있습니다 * - 아마 인라인으로 더 좋은 기회를 가질 수 있습니다. – peterchen

+0

구현 단계에서이 문제를 해결할 수있는 구현 관련 기능이 있습니다. MS 구현에서는'__declspec (selectany)', GCC에서는'__attribute __ ((weak))'와 비슷합니다. – AnT

답변

12

을, 당신은 링커 오류를 방지하기 위해 inline를 사용해야합니다.

그렇지 않으면 헤더 파일에서 함수를 선언하고 소스 파일에서 해당 구현을 별도로 제공 할 수 있습니다.

+0

물론 "인라인"을 사용하면 함수가 인라인 될 기회가 증가하므로 해당 헤더를 사용하는 응용 프로그램에서 코드가 부풀어 올 수 있습니다. –

8

당신은 inline 키워드를 사용할 수 있습니다 : 당신이 정말로 (를 선언 반대) 함수를 정의하려면

inline void wont_give_linker_errors(void) 
{ 
    // ... 
} 
1

이미 언급 한 inline 외에도 대부분의 컴파일러 템플릿은 헤더 (그리고 모든 컴파일러가 허용됨)에 정의되어야합니다. 부스트는 주로 템플릿이기 때문에 이것이 거의 모든 헤더 인 이유를 설명합니다.

-1

사람들은 inline을 제안했지만 질문의 첫 번째 부분을 위반하는 것으로 나타납니다. 즉, 함수 정의가 호출 될 때 코드에 전체 정의가 삽입되므로 코드가 커집니다. 따라서 전체 질문에 대한 대답은 "아니오"입니다. 당신이 바르게 지적했듯이 그들은 여전히 ​​각 소스 파일에 정의되어 있습니다 만 및 코드 크기가 문제가되는 경우 그래서 inline보다 더 나은 옵션입니다 static으로 당신이 그들을 표시하면

. 링커가 복제본을 찾아 내고 병합 할 수 있는지 여부는 알 수 없습니다. 나는 의심하지 않는다.

편집 :

가 마찬가지로 내가 static를 사용 및/또는 헤더 내에서 함수를 정의의 개념을 지원하는지 여부에 혼란을 정리하기 위해 일반적으로 나는 그렇지 안심 파일. 이는 단순히 헤더 파일에 정의 된 inlinestatic 기능 사이의 차이에 대한 기술적 인 응답을 의미했습니다. 아무것도 더.

+1

'inline'에는 두 가지 역할이 있습니다. 첫째, 다중 정의가 오류가되지 않도록합니다. 둘째,이 함수가 인라인 될 수 있다는 것은 컴파일러에게 ** 힌트 **입니다. 실제로 컴파일러는 큰 기능을 인라인하지 않습니다 (예 : 유일한 경우는 제외). – peterchen

+0

그 반대의 경우가 아닙니까? "사용하지 않은"경고를 유발하는 정적 함수는 정확하지 않습니까? 정적 인 것은 파일을 포함하는 각각의 파일이 자신의 버전의 함수를 얻는다는 것을 의미하지 않으며, "주문 제작"이기 때문에 그들이 모두 그것을 어딘가에 사용한다면 실제로 좋을 것이다.) – UncleBens

+0

@peterchen : 나는 힌트라는 것을 안다. 그래서 최악의 시나리오를 설명하고 있습니다. 분명히 말하지 않은 것입니다. – Troubadour

2

어 ... 질문에 대한 답변은 이 아닙니다.이 아닙니다. 은 인라인이 아닌 한 헤더 파일의 함수를 정의하지 마십시오.

'정적'기능도 헤더에 정의 할 수 있지만 아주 드문 경우에만 유용합니다. 다중 정의 문제를 해결하기 위해 '정적'을 사용하는 것은 완전히 난센스입니다.

다시 헤더 파일은 정의되지 않은 함수 선언을위한 것입니다. 왜 지구상에서 을 정의 하시겠습니까? 기능이 있습니까?

당신은 "헤더 라이브러리"를 쓰고 있다고하셨습니다. "헤더 라이브러리"란 무엇입니까? Boost는 "함수"가 실제로 함수가 아니기 때문에 헤더 파일에 "함수"를 정의합니다. 함수 템플릿입니다. 함수 템플릿은 헤더 파일에 정의되어야합니다 (거의, 거의). 그게 아니라면, Boost는 헤더 파일에 무엇인가를 정의하는 것과 같은 이상한 일을하지 않을 것입니다.

+0

Er ...., 템플릿. :) 그럼에도 불구하고 우수한 점. 나는 내 대답에'정적'을 사용하는 기술적 인 성질을 다루었지만 그 정확성에 대해서는 언급하지 않았다. – Troubadour

+0

OP가 템플릿을 정의하는 경우, 그는 처음에는 여러 정의 문제가 발생하지 않습니다. 또한, 내가 관찰하려고 항상 노력하고있는 용어적인 차이점이 있습니다 : * function template *은 * function *이 아닙니다. – AnT

+0

예 템플릿을 사용하고 있다면 그 문제가 없다는 것을 알고 있습니다. 그것이 빵 값과 무슨 상관이 있습니까? 나는 비 템플릿 함수를 참조하기 위해 "함수"를 사용하고 있다는 사실에 대한 귀하의 말씀을 받아야 할 것입니다. 널 유감스럽게 생각해서 미안해. – Troubadour

관련 문제