2011-08-09 5 views
8

그 클래스 안에서 사용되지 않는 private 메서드는 컴파일러/링커에 의해 제거되어 최종 이진 파일에 포함되지 않을 것이라고 생각했습니다.최종 바이너리에서 사용되지 않는 메소드를 제외하는 방법은 무엇입니까?

구현되었지만 사용되지 않는 개인 메서드로 예제 클래스를 만들었습니다.

class XXX 
{ 
    public: 
    XXX(); 

    private: 
    void MyUnusedMethod(); 
}; 

및 구현 파일에

:

void XXX::MyUnusedMethod() 
{ 
    const char* hugo = "ABCCHARLYABC"; 
    printf(hugo); 
} 

컴파일 후 문자열은 여전히 ​​최종 바이너리에 존재합니다. 왜? 어떻게 이것을 막을 수 있습니까?

안부, CHARLY

+0

왜 그 방법을'#if 0 ... #endif' 블록에 넣을 수 없습니까? – iammilind

+0

gcc의 최적화 플래그를 조정 해 보셨습니까? – slaphappy

+0

'-O3' 플래그를 사용한다면 아무런 차이가 없습니다. 물론 - 내가 더 이상 사용하지 않을 것이라는 것을 안다면 나는 그것을 제거하기에는 너무 게을 리지 않습니다. 그러나 일반적인 질문이기도합니다 : 왜 컴파일러/링커에 의해 삭제되지 않습니까? – Charly

답변

7

하나의 유용한 방법은 각 기능에 대해 .o 파일을 만드는 것입니다. 그런 다음 .o 파일에서 .a 아카이브를 빌드하십시오. 해당 아카이브에 링크 할 때 링커는 기호를 확인하는 .o 파일, 즉 아무도 호출하지 않는 함수가있는 .o 파일에만 링크합니다. link-time code generation으로 최신 버전의 gcc를 사용하는 것이 좋습니다.

+1

+1은 링크 타임 코드 생성에 이상적입니다. – Veger

1

이 아마 정말 나쁜 생각이지만, 어쨌든 그것을 작성해야 :) 당신은 템플릿 클래스를 만들 수는 afair 사용하지 않는 방법을 삭제할.

+0

어? 정말? afaik, 어떤 instantiations 모든 코드를해야합니다 .. – Nim

+0

나는 정말 그걸 확인해야합니다, 내가 그 어딘가에 읽었 생각. 지금 당장 템플릿 북을 가지고 있지 않습니다./ – duedl0r

+0

대답은 정확합니다.그 이유는'class Foo '는 모든 메소드가'T'의 모든 값에 대해 컴파일되지는 않을지라도 유용 할 수 있다는 것입니다. 예 : 'T == const int'는'Foo '의 모든 비 const 메소드를 깨뜨릴 수 있습니다. – MSalters

3

컴파일 후 문자열은 여전히 ​​최종 이진 파일에 있습니다. 이유

다른 사람들은 최종 바이너리에서 사용되지 않는 코드를 제거하는 방법을 제안했습니다. Why에 대해 약간의 답을주고 싶습니다. 기능을 제거 할 수없는 이유는 두 가지입니다.

당신이 static linkage와 그 XXX 유형의 모든 개체를 선언하지 않는 한 다른 객체 파일이 extern를 사용하여 값을 액세스 할 수 있기 때문에, 컴파일러가 생성 된 오브젝트 파일의 유형 (따라서 방법)을 제거 할 수 없습니다. 한 번에 모든 객체 파일을 볼 수있는 링커가이 문제를 해결할 수 있습니다.

그러나 질문을 gcc으로 태그 했으므로 컴파일하지 않았거나 -fvisibility=hidden으로 연결했을 수 있습니다. 이 경우 링커조차도 다른 모듈이 런타임에 심볼을 해석 할 수 있으므로 심볼 (따라서 코드)을 제거 할 수 없습니다.

+0

"(따라서 방법)"은 전제에서 따르지 않습니다. 개체의 수에 관계없이'MyUnusedMethod'에 대한 호출이 없으면 이진 파일에있을 필요가 없습니다. – MSalters

+0

@MSalters : 'MyUnusedMethod'의 심볼이 최종 모듈 (예 : 공유 라이브러리의 실행 파일)에서 생략되지 않으면 런타임에 다른 모듈이 심볼을 해석하고 액세스하는 것일 수 있습니다. 모듈 내에서 사용되지 않는 코드는 모듈에 남아 있기 때문에 매우 일반적입니다. 공유 라이브러리에 의해 노출 된 함수를 생각해보십시오. –

7

이것은 일반적으로 -funcata-sections 옵션을 gcc에 전달하여 수행됩니다. 자세한 내용은 link을 참조하십시오.

관련 문제