我懷疑gcc 4.8.3是否內聯錯誤的模板函數......在調試模式下不會發生此問題,但僅在優化模式下。然而,這發生在一個複雜的代碼庫中,我無法在簡單的測試用例中重現該問題。gcc內嵌通用模板函數與專門定義
我的代碼是像下面
在調試版本,它打印出A,而在優化的建立,它打印出在這裏?\ NB
我想任何內襯採用通用模板函數定義但不是專門定義的。但屬性((noinline))沒有幫助。
有沒有人,如果我的代碼有C++定義的行爲?以及如何解決這個問題?
我懷疑gcc 4.8.3是否內聯錯誤的模板函數......在調試模式下不會發生此問題,但僅在優化模式下。然而,這發生在一個複雜的代碼庫中,我無法在簡單的測試用例中重現該問題。gcc內嵌通用模板函數與專門定義
我的代碼是像下面
在調試版本,它打印出A,而在優化的建立,它打印出在這裏?\ NB
我想任何內襯採用通用模板函數定義但不是專門定義的。但屬性((noinline))沒有幫助。
有沒有人,如果我的代碼有C++定義的行爲?以及如何解決這個問題?
你沒有明確說明這一點,但我猜你在你的實際代碼中沒有聲明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.h
,A.cpp
重現您的問題,和main.cpp
,其中A.cpp
包含了專門的定義,這樣,當main.cpp
包括A.h
,它是不知道何時優化期間內聯發生了,當與-O0
編譯,不會出現內聯,所以WriteNative()
獲取A.cpp
對定義鏈接的專業化。
編輯: 看到這個answer哪些引用規範解釋爲什麼這是正確的行爲。
14.7.3 [temp.expl.spec]:
6 /如果模板,一個構件模板或模板類中的成員是 明確地專門則該專業化應前的聲明 首先使用那種會導致 隱式實例化的特化,在 的每個翻譯單元中發生這種使用;不需要診斷。如果程序 未提供明確專業化的定義,或者專業化的使用方式會導致發生隱式實例化或成員是虛擬成員 函數,則該程序是格式不正確的,不需要診斷。對於已聲明但未定義的明確 專用,永遠不會生成隱式實例化。
是否在C++所請求的頭文件中聲明瞭特化? –
不是。但其他編輯部門顯然不會看到它。這是編譯過程中發生的事情以及鏈接期間發生的事情 –
@ n.caillou如果不需要,優化對我來說似乎過於激進。我認爲編譯器優化不應該改變代碼的工作方式,除非我的原始代碼沒有定義。 –
我發現的解決方法是通過內聯專用定義:http://stackoverflow.com/questions/4445654/multiple-definition-of-template-specialization-when-using-different-objects。 –