2017-05-03 23 views
0

我懷疑gcc 4.8.3是否內聯錯誤的模板函數......在調試模式下不會發生此問題,但僅在優化模式下。然而,這發生在一個複雜的代碼庫中,我無法在簡單的測試用例中重現該問題。gcc內嵌通用模板函數與專門定義

我的代碼是像下面

​​

在調試版本,它打印出A,而在優化的建立,它打印出在這裏?\ NB

我想任何內襯採用通用模板函數定義但不是專門定義的。但屬性((noinline))沒有幫助。

有沒有人,如果我的代碼有C++定義的行爲?以及如何解決這個問題?

+0

我發現的解決方法是通過內聯專用定義:http://stackoverflow.com/questions/4445654/multiple-definition-of-template-specialization-when-using-different-objects。 –

回答

2

你沒有明確說明這一點,但我猜你在你的實際代碼中沒有聲明A的.h文件中的專門化。所以當A.h被包含在一個單獨的編譯單元中時,編譯器不知道WriteNative()的特殊化。添加專業化應該可以解決這個問題的聲明,而不必包含在同一個文件中的定義(即不具有內聯的話):

class A { 
    public: 
    template<typename T> int WriteNative(const T) { 
     printf("here?\n") 
     return 0; 
    } 

    template<typename D> 
     void doit() { 
     if (WriteNative<double>(1)) { 
      printf("A\n"); 
     } else { 
      printf("B\n"); 
     } 
    } 
}; 
template<> int A::WriteNative(const double); 

您可以通過使用三個文件A.hA.cpp重現您的問題,和main.cpp,其中A.cpp包含了專門的定義,這樣,當main.cpp包括A.h,它是不知道何時優化期間內聯發生了,當與-O0編譯,不會出現內聯,所以WriteNative()獲取A.cpp對定義鏈接的專業化。

編輯: 看到這個answer哪些引用規範解釋爲什麼這是正確的行爲。

14.7.3 [temp.expl.spec]:

6 /如果模板,一個構件模板或模板類中的成員是 明確地專門則該專業化應前的聲明 首先使用那種會導致 隱式實例化的特化,在 的每個翻譯單元中發生這種使用;不需要診斷。如果程序 未提供明確專業化的定義,或者專業化的使用方式會導致發生隱式實例化或成員是虛擬成員 函數,則該程序是格式不正確的,不需要診斷。對於已聲明但未定義的明確 專用,永遠不會生成隱式實例化。

+0

是否在C++所請求的頭文件中聲明瞭特化? –

+1

不是。但其他編輯部門顯然不會看到它。這是編譯過程中發生的事情以及鏈接期間發生的事情 –

+0

@ n.caillou如果不需要,優化對我來說似乎過於激進。我認爲編譯器優化不應該改變代碼的工作方式,除非我的原始代碼沒有定義。 –