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和clang 3.2中。

任何想法?

回答

1

您可以通過stupid定義後加入

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

解決這個問題。

這是因爲主叫的 t非靜態成員函數需要的t地址被當作this指針來使用。考慮一個對象的地址使得它需要一個運行時實例,它需要上述定義。

+0

謝謝!任何想法爲什麼它發生? – 2013-03-17 00:38:17

+0

@ArewrewSpott:基本上,程序是不合格的,因爲't'是odr使用的,但鏈接器不需要爲這個錯誤產生診斷。所以它可能會也可能不會,但程序仍然不健全。請參閱[this](http://stackoverflow.com/questions/14547986/what-am-i-allowed-to-do-with-a-static-constexpr-in-class-initialized-data-memb) – 2013-03-17 00:46:54

+0

@AndyProwl :什麼是「odr-used」? – 2013-03-17 01:01:57

相關問題