C 컴파일러는 .a 파일에 정적으로 링크할 때 사용되지 않는 함수를 삭제합니까?

C 컴파일러는 .a 파일에 정적으로 링크할 때 사용되지 않는 함수를 삭제합니까?

main.c에 정적으로 링크된 라이브러리가 있다고 가정해 보겠습니다 libmine.a. 라이브러리에 대한 정적 링크로 인해 라이브러리 함수가 컴파일 시 기본 실행 파일에 포함됩니다.

libmine.a사용되지 않는 함수가 제공되는 경우 main.c컴파일러(예: GCC)가 이러한 함수를 폐기합니까?

이 질문은 정적 라이브러리를 사용하면 실행 파일이 더 커진다는 "공통 메시징"에서 영감을 얻었으므로 컴파일러가 최소한 아카이브에서 사용하지 않는 코드를 제거하는지 궁금합니다.

답변1

기본적으로 링커는 개체 파일을 전체적으로 처리합니다. 귀하의 예에서 실행 파일에는 궁극적으로 main.c( )의 코드 와 main.o사용된 모든 기능을 제공(전달)하는 데 필요한 모든 개체 파일 libmine.a(개체 파일 아카이브) 이 포함됩니다 main.c.

따라서 링커에 반드시 다음이 포함될 필요는 없습니다.모두, libmine.a그러나 사용할 수 있는 세분성은 함수(기본값)가 아니라 개체 파일(엄격히 말하면 섹션)입니다. 그 이유는 .c특정 파일을 객체 파일로 컴파일할 때 소스 코드의 정보가 손실되기 때문입니다. 특히 함수의 끝은 저장되지 않고 함수의 시작만 저장되며 여러 함수가 결합될 수 있기 때문입니다. , 기능을 사용하지 않을 때 실제로 삭제할 수 있는 항목을 개체 파일에서 결정하는 것은 어렵습니다.

그러나 컴파일러와 링커는 필요한 추가 정보에 액세스할 수 있으면 더 나은 작업을 수행할 수 있습니다. 예를 들어, 1980년대 Mac의 LightspeedC 프로그래밍 환경은 프로젝트를 라이브러리로 사용할 수 있었으며 이 경우에는 완전한 소스 코드가 있었기 때문에 실제로 필요한 기능만 포함하게 되었습니다.

보다 현대적인 시스템에서는 링커가 함수를 개별적으로 처리할 수 있도록 하는 개체 파일을 생성하도록 컴파일러에 지시할 수 있습니다. GCC를 사용하여 옵션이 활성화된 파일을 빌드하고 .o최종 프로그램을 해당 옵션과 연결합니다. 이는 특히 특정 클래스의 최적화를 방지하는 데 영향을 미칩니다.-ffunction-sections -fdata-sections--gc-sectionsGCC에서 사용하지 않는 함수를 폐기합니다.더 알아보기.

최신 컴파일러 및 링커에서 사용할 수 있는 또 다른 옵션은 링크 시간 최적화입니다 -flto. 최적화가 활성화된 경우(예를 들어 -O2개체 파일을 컴파일할 때 링커는 결과 바이너리에 사용되지 않은 함수를 포함하지 않습니다. 그렇지 않더라도 -ffunction-sections -fdata-sections.

답변2

예. 그러나 이는 기능이 아닌 모듈 수준에 있습니다.

예를 들어, foo_goo.c와 bar.c라는 두 개의 소스 파일이 있습니다.

// foo_goo.c
int foo() { .. };
int goo() { .. };
// bar.c
int bar() { .. };

이를 합산하여 foo_goo.o아카이브 에 bar.o보관합니다 ..olibmine.a

이제 함수 main()를 호출하기만 하면 됩니다 foo().

// main.c
int main(int argc, char **argv) {
   return foo();
}

이 소스 파일을 로 컴파일 main.o하고 링크합니다 .a.

링커는 foo()모듈의 함수를 보고 foo_goo.o사용하게 되며, main()함수가 foo()참조되고, goo()함수는 최종 바이너리에 추가되지만 참조되지는 않습니다. bar.o참조된 이름이 없으므로 무시됩니다 .

답변3

이것은 컴파일러와 아무 관련이 없습니다. 정적 링크를 사용하는 경우 링커는 필요한 모든 개체를 하나의 파일에 저장합니다.

이것은 C 프로그램의 main() 함수, main이 사용할 수 있는 모든 것, main이 사용할 수 있는 일부 기능 등이 될 것입니다. 호출할 수 없는 함수나 액세스할 수 없는 개체가 있는 경우 링커는 이를 무시할 수 있습니다. 개체 파일에 호출할 수 있는 5개의 함수와 호출할 수 없는 10개의 함수가 포함되어 있는 경우 링커는 처음 5개만 포함할 수 있습니다.

관련 정보