2012-01-17 2 views
9

현재 STM32 플랫폼에 포함 된 C++ 개발과 관련되어 있습니다. 우리 팀은 다양한 저수준 하드웨어 장치의 드라이버를 매개 변수화하기 위해 템플릿 사용을 평가하고 있습니다.사용되지 않는 템플릿 인스턴스화 정적 멤버 제거

유효한 템플릿 특수화는 모두 미리 알고 있으므로 구현 파일 내에서 모든 유효한 특수화를 명시 적으로 제공 할 수 있습니다 (구현 및 선언 구분). 실제로 우리에게 명시 적 전문화는 실행 가능한 매개 변수 세트를 문서화하는 데 도움이되므로 매우 유용합니다. 일반적으로 단지 전문 분야 중 하나가 실제로 사용됩니다 비록

// file i2c_dev.h 

template<typename traits> 
struct i2c_dev 
{ 
public: 
    static void init(); 
    static void send(); 
    static bool busy(); 
    ... 
private: 
    static i2c_transfer periodic_transfer; // class with used-defined constructor 
}; 

// traits class for configuration A 
struct i2c_dev_traitsA 
{ 
    enum 
    { 
     I2Cx_BASE = I2C1_BASE 
    , PORTx_BASE = GPIOB_BASE 
    , PORTx_PIN_TX = PB08 
    , PORTx_PIN_RX = PB09 
    }; 
}; 

// traits class for configuration B, different I2C peripherial and pinout 
struct i2c_dev_traitsB 
{ 
    enum 
    { 
     I2Cx_BASE = I2C2_BASE 
    , PORTx_BASE = GPIOA_BASE 
    , PORTx_PIN_TX = PA01 
    , PORTx_PIN_RX = PA02 
    }; 
}; 

// file i2c_dev.cpp 

// Implementation of template functions 
template<typename traits> 
void i2c_devy<traits>::init() { ... } 

... 

// explcitly specialize for all valid traits classes 
template class i2c_dev<i2c_dev_traitsA>; 
template class i2c_dev<i2c_dev_traitsB>; 

는 사용되지 않는 전문화에 대해 생성 된 코드는 정확히 우리가 원하는 것입니다 링커에 의해 최종 이미지에서 제거됩니다.

그러나 각 템플릿 전문화의 정적 멤버 변수 - periodic_transfer -은 arm-none-eabi-nm 도구로 생성 된 메모리 맵에서 볼 수있는 것처럼 실행 파일에 남아 있습니다. 이는 아마도 i2c_transfer이 POD가 아니지만 사용자 정의 생성자를 가지고 있기 때문일 수 있습니다. 생성자를 제거하고 POD 유형으로 변환하면 정적 멤버도 사라집니다.

명시 적으로 인스턴스화되었지만 사용되지 않은 템플릿의 정적 POD 멤버를 제거 할 수있는 방법이 있습니까?

감사합니다, 아르네

편집 # 1 : 문제를 다시 생각하면 나는 분명히 문제가 해결 다음과 같은 솔루션을 함께했다.

클래스 사실 그것은 단지 명확하고 사용하기 쉽게 생성자의 한 i2c_transfer는 데이터 구성원이 같은 POD 기본 클래스 i2c_transfer_pod로 이동이있는 경우 : 다음

struct i2c_transfer_pod 
{ 
protected: 
    uint16_t m_size; 
    char* m_buffer; 
}; 

struct i2c_transfer : public i2c_transfer_pod 
{ 
public: 
    i2c_transfer(); 
    i2c_transfer(i2c_direction_enum dir, char*buffer, uint16_t count); 

    bool failed(); 
    bool succeeded(); 
}; 

, 사용되지 않는 i2c_dev<traits>의 정적 멤버 특수화는 최종 실행 파일에서도 제거됩니다 (맵 파일에서 제안하는대로).

편집 # 2 : one-self에 대한 답변이 다소 불편할지라도 제안 된 해결책에 대한 의견을 보내 주시면 감사하겠습니다. 가능하면 좀 더 우아한 방법이 있을까요? 컴파일러가 실제로 추가 파생을 최적화하는 것으로 추정합니까?

편집 # 3 : 솔루션이 나에게 효과적이기 때문에 질문을 닫습니다. 관찰 된 행동에 대한 이유에 대해 더 깊은 통찰력을 갖는 것이 좋을 것입니다. 문제를 다시 생각하면 내가 분명히 문제가 해결 다음과 같은 솔루션을 내놓았다 :

문제의 컴파일러는 arm-none-eabi-gcc (Sourcery G++ Lite 2011.03-42) 4.5.2

+1

문제의 해결책을 찾은 경우 대답으로 게시해야합니다. –

+1

이상한 컴파일러 진드기처럼 들리지만 실제로는 별다른 차이가 없어야합니다. – Xeo

+0

어떤 절름발이 컴파일러이고, 어떤 버전입니까? –

답변

2

답변 (편집 # 1)입니다.

클래스 사실 그것은 단지 명확하고 사용하기 쉽게 생성자의 한 i2c_transfer는 데이터 구성원이 같은 POD 기본 클래스 i2c_transfer_pod로 이동이있는 경우 : 다음

struct i2c_transfer_pod 
{ 
protected: 
    uint16_t m_size; 
    char* m_buffer; 
}; 

struct i2c_transfer : public i2c_transfer_pod 
{ 
public: 
    i2c_transfer(); 
    i2c_transfer(i2c_direction_enum dir, char*buffer, uint16_t count); 

    bool failed(); 
    bool succeeded(); 
}; 

, 사용되지 않는 i2c_dev<traits>의 정적 멤버 특수화는 최종 실행 파일에서도 제거됩니다 (맵 파일에서 제안하는대로).

관련 문제