2017-11-25 4 views
0

하나의 템플릿 클래스를 포함하는 고안된 헤더 파일과 하나의 중복 함수와 함께 템플릿 클래스의 인스턴스를 정확하게 포함하는 두 개의 소스 파일이 있다고 가정합니다. 즉 ...이다템플릿 인스턴스화 - 컴파일러가 중복 된 심볼을 어떻게 피합니까?

인위적인 헤더 (thing.hpp)

#pragma once 

template <typename T> 
class Thing { 
    public: 
    T t; 
    public: 
    T& value() { 
     return t; 
    } 
}; 

thing.cpp :

#include <thing.hpp> 

template class Thing<int>; 

int MeaningOfLife() { 
    return 42; 
} 

thingy.cpp (thing.cpp 정확히 같은)

OS X에서 clang을 사용하여 컴파일 및 연결 (link) 한 후에는 MeaningOfLife 만 중복 된 기호로 보였지만 템플릿 인스턴스화 기호 (단지 Thing::value()) 하지 않았다. 해체를 면밀히 검사하면 Thing::value()의 심볼에 .weak_definition이라는 기호가 붙은 것 같습니다.

질문 0 :이 지시문은 기호가 다중 정의되지 않도록하기 위해 무엇을하고 있지만 실제로 무엇을하고 있습니까?

질문 1 : 다른 컴파일러가 어떻게이 작업을 Linux, Windows 등에서 할 수 있습니까?

질문 2 : 복제 된 템플릿 인스턴스화 중 하나의 어셈블리 코드를 잘못 변형 한 경우 어떻게해야합니까? 즉, 동일한 기호, 다른 기능 본문입니다. 스마트 컴파일러가 불일치를 감지합니까?

답변

1

대충 Google 검색은 어떤 상태, these OSX docs로 우리를 인도 :

.weak_definition 지시어는 약한 정의 할 symbol_name됩니다. symbol_namecoalesced 섹션에서만 정의 할 수 있습니다. 이것은 C++ 컴파일러에서 템플리트 인스턴스화를 지원하는 데 사용됩니다. [...]

따라서 그것은 coalesced 정의로 진행 :

coalesced 부 어떤 명령들 또는 데이터를 포함 할 수 있고, 심볼의 하나 이상의 정의가 여러 정의 될 수있는 경우에 사용 오브젝트 파일이 함께 링크됩니다. 정적 링크 편집기는 병합 된 심볼과 연관된 데이터를 링크 된 첫 번째 오브젝트 파일에서 유지하고 다른 오브젝트 파일의 데이터를 자동으로 삭제합니다. coalesced 섹션의 예는 컴파일러가 C++ 템플릿의 암시 적 인스턴스화를위한 코드를 생성 한 섹션입니다.

당신이 정의 (나는 그것을 시도하지 않은) 중 하나를 수정 한 경우 내가 무슨 일이 일어날 지 모르겠지만, 워드 프로세서 링커 그냥 맹목적으로 처음 발견 중 하나를 취 것을 의미한다.

+0

필자는 이전에 이것을 보았지만 OS X에서만 나타나는 것처럼 보입니다. 다른 시스템에서 어떤 일이 일어나는지 궁금합니다. –

+0

@MonatheMonad 다른 시스템에서도 비슷한 기능을 수행합니다. 언어 스펙은 여러 유형의 템플리트 정의를 허용합니다. 그것들은 모두 일치해야하지만 컴파일러 (링커)가 찾은 첫 번째 것을 취하지 않으면 진단을 내릴 필요가 없습니다. – 1201ProgramAlarm