3

나는 -Ox로 컴파일 코드가 잘 컴파일 이상한 문제에 봉착하지만, -g로 컴파일 코드는 다음과 같은 오류와 함께 링크에 실패디버그 빌드에서 템플릿 대체가 실패했지만 최적화 된 빌드에서 작동합니까?

Undefined symbols for architecture x86_64: 
    "stupid<dummy>::t", referenced from: 
     stupid<dummy>::operator()(int, int) const in main.o 

이 문제 재현 코드 :

struct dummy { void operator()(const int a, const int b) const {} ; }; 

template <typename T> 
struct stupid { 
constexpr static T t = T(); // create a new one; 

stupid() {}; 
void operator()(int a, int b) const { t(a, b); } 
}; 


int main() 
{ 
const stupid<dummy> a; 
a(1, 2); 
} 

코드가 최적화되면 함수가 인라인되고 외부 함수 호출이 필요하지 않지만 코드가 최적화되어 있지 않으면 함수가 호출되지만 존재하지 않는 것처럼 보입니까? (나는 그것이 왜 거기에 있지 않은지 확신하지 않는다. ..). 이것은 g ++ 4.7과 4.8에서 발생하고 3.2에서 발생합니다.

아이디어가 있으십니까?

답변

1

당신은 stupid의 정의 후

template<typename T> constexpr const T stupid<T>::t; 

를 추가하면이 문제를 해결할 수 있습니다. t의 비 정적 멤버 함수를 호출하면 t의 어드레스가 this 포인터로 사용하는 촬영해야하기 때문에

이다. 객체의 주소를 가져 오면 런타임 인스턴스가 필요하며 위의 정의가 필요합니다.

+0

감사합니다. 왜 그런 일이 일어나는 지 아십니까? –

+0

@AndrewSpott : 기본적으로 't'는 odr- 사용 되었기 때문에 프로그램이 잘못 작성되었지만 링커는이 오류에 대한 진단을 생성 할 필요가 없습니다. 그렇게 할지라도 프로그램은 여전히 ​​부적절합니다. [this] (http://stackoverflow.com/questions/14547986/what-am-i-allowed-to-do-with-a-static-constexpr-in-class-initialized-data-memb) –

+0

@AndyProwl : "odr-used"란 무엇입니까? –