2010-12-05 1 views
2

나는 정적 라이브러리 (lib.a)와 그것에 링크되어있는 프로그램을 가지고있다. 라이브러리에는 사용하기 전에 항상 호출되는 진입 점이 없지만 프로그램의 초기에 코드를 실행해야합니다 (main()이 시작되기 전에 가능). 그래서 나는 내 자신의 클래스의 정적 변수를 사용할 것이라고 생각했다.링커는 정적 라이브러리를 연결할 때 객체 파일을 생략 할 수 있습니까?

#include <MyClass.h> 
static MyClass myVar; 

다음과 같은 내용을 포함하는 새로운 소스 파일을 추가했습니다. MyClass의 생성자가 내 코드를 실행합니다. lib.a를 링크하고 "nm"을 실행하면 myVar가있는 정보를 얻습니다. 그러나 내 프로그램을 연결하고 "nm"을 시도하면 myVar가 표시되지 않습니다. 이 코드를 기존 파일에 넣으면 심볼이 최종 실행 파일에 표시됩니다. 왜 그런가요? 링커가이 경우 lib.a 라이브러리에서 객체 파일을 생략 할 수 있습니까? 나는 변수가 외부에서 참조되지 않는다는 것을 알고있다. (정적이어서는 안된다.)하지만 코드를 자체적으로 실행해야한다. 따라서 제거되어야하는 이유가 없다.

차이가 나는 경우 오래된 SunPro 컴파일러를 사용하고 있습니다.

+1

전역 변수 초기화에 의존하는 코드를 작성하는 것은 나쁜 생각입니다. 어떻게하면 더 나은가? – ybungalobill

+0

@ybungalobil : 유용 할 수 있습니다. 예 : 단위 테스트. (이것은 대부분의 C++ 단위 테스트 프레임 워크가 자동 테스트 등록을 처리하는 방법입니다.) @ 토마스 : 어떤 컴파일러/플랫폼을 사용하고 있습니까? –

+0

@Billy : 유용 할 수 있지만 많아야 하나의 구성 요소 만이 유용합니다. 그렇지 않으면 정말 나쁜 것을 얻을 수 있습니다 (초기화 순서가 정의되지 않았습니다). 또한 그는 "오래된 SunPro 컴파일러"를 사용한다고 썼다. – ybungalobill

답변

0

링커의 기능은 꽤 표준 적입니다. C++ 표준을 의미하며, 일반적으로 관찰자의 행동), 당신은 그 문제를 해결할 수 있습니다. GNU ld에서는 --whole-archive 옵션이고, Sun 도구의 경우에는 -z allextract입니다. 어느 것이 실제로 내 프로젝트에서 기대했던대로 작동하지 않았기 때문에 약한 기호를 가진 마법을 사용하여 내가 원하는 것을 얻었습니다. -z weakextract.

1

기술적으로 말하면 링커는 프로그램을 컴파일하는 동안 해당 오브젝트 파일을 포함시켜야합니다. 그러나 이것에 대한 지원은 많은 컴파일러에서 버그가 있습니다 (예 : MSVC++). 주 프로그램의 어딘가에 외부 참조를 추가하면 해당 오브젝트 파일을 포함시켜야합니다.

또한 nm의 경우 정적 초기화 프로그램이 인라인 된 것이므로 기호가 최종 이진 파일에 존재하지 않아도됩니다. 정적으로 부작용이있는 무언가 (예 : std::cout 문)를 사용하고 컴파일러를 비난하기 전에 실행되지 않는지 확인하십시오.

+0

그것이 작동하지 않는다는 것을 알고 있습니다. 그래서 nm으로 조사하기 시작했습니다. 일반적으로 작동해야하는 정보를 주셔서 감사하지만, C++/다른 표준에 의해 정의되었는지 또는 다른 컴파일러에서 작동하는지 여부를 알면 좋을까요? –

+0

@Tomasz : C++ 표준은 최종 바이너리를 어셈블하는 방법에 대해서는 아무 말도하지 않습니다. (표준은 정적 또는 동적 라이브러리의 존재를 알지 못합니다.) 이것은 표준이 기계 중립적으로 작성되고 많은 라이브러리 (특히 코드와 데이터를 분리하는 라이브러리)에서는 가능하지 않기 때문에 가능합니다. –

관련 문제