簡體   English   中英

模板化鏈接在-O2上不起作用,但在-O0上起作用

[英]Templated linkage does not work on -O2, but does on -O0

我編寫了一個C ++程序,它使用cmake綁定並在Debian機器上運行。 我很高興地說所有已知的主要錯誤都得到了糾正,我覺得我已經准備好了

add_definitions(-Wall)
set(CMAKE_BUILD_TYPE Debug)
add_definitions("-O0 -std=c++0x")

一路走來

add_definitions("-O2 -std=c++0x")

我做到了這一點,突然間我的項目中的一個模板化的類(在一些頭文件中天真地聲明並在一些單獨的.cpp中為所有用例定義)在鏈接期間中斷了一堆“未定義”錯誤。

對這個論壇的一些研究產生了這樣的線程: 為什么模板只能在頭文件中實現? 我相信我看到Luc在他着名的答案中正在推動:編譯器實際上為每個模板化類所需的版本“編寫代碼”(即T = int,T = float,T = what_ever_else),為此需要訪問實際的實施。

很公平。 但是在這里完全令我感到困惑的是:在嘗試優化編譯時,這顯然只是一個問題。 使用“-O0”一切正常。 怎么可能?

附錄

1.)關於重復的嫌疑人:這里的問題不是我所做的那是錯的。 我的罪很清楚:我將模板化函數定義在頭文件的范圍之外,由於上述原因和我已經引用過的帖子,顯然不允許這樣做。

鑒於所述引用帖子的真實性,很明顯我的程序無法編譯。 我不明白的是:為什么用-O0編譯。

2.)nos要求一些明確的錯誤。 我上次嘗試使用-O2的結束仍然在我的終端緩沖區中(抱歉,編譯大約需要一個小時,因此不容易再現)。 但是因為它在連接過程中斷了。 這就是我仍然可以將鼠標指針放在:

/home/kochmn/projects/free_sentinel_gl/sentinel/src/game/game.cpp:432: undefined reference to `game::Board<game::Figure>::get(QPoint)'
libqt.a(game.cpp.o): In function `game::Game::hyperspace_jump()':
/home/kochmn/projects/free_sentinel_gl/sentinel/src/game/game.cpp:950: undefined reference to `game::Board<game::Square>::get(QPoint)'

[... many more like that all concerned about the templated class "Board"
  which is declared in landscape.h, defined in landscape.cpp and
  used pretty much everywhere else ... ]

collect2: error: ld returned 1 exit status
CMakeFiles/sentinel.dir/build.make:548: recipe for target 'sentinel' failed
make[2]: *** [sentinel] Error 1
CMakeFiles/Makefile2:127: recipe for target 'CMakeFiles/sentinel.dir/all' failed
make[1]: *** [CMakeFiles/sentinel.dir/all] Error 2
Makefile:76: recipe for target 'all' failed
make: *** [all] Error 2

3.)關於評論問題“如何定義用例?”:讓我們利用GitHub這一事實。

所有用例都在這里定義: https//github.com/kochsoft/free_sentinel_gl/blob/master/sentinel/src/game/landscape.cpp#L507,從第507行開始。

標題在這里: https//github.com/kochsoft/free_sentinel_gl/blob/master/sentinel/src/include/landscape.h#L363從363行開始的相關段落。

我的問題已經解決,dyp與他/她的評論最接近。 神奇的詞是“顯式模板instanciation”,可以在這里找到: http//www.cplusplus.com/forum/articles/14272/

我沒有用我的定義混亂我的頭文件。 我也沒有在標題中添加像#include“some.cpp”這樣的代碼,在我看來這相同。 相反,我添加了線條

template class Board<Figure>; 
template class Board<Square>;

在landscape.cpp的定義下,並能夠使用-O2進行編譯。

根據為什么模板只能在頭文件中實現? 除了我的板上的數字和正方形之外,我將無法使用任何其他東西(這很適合我)。

至於為什么-O0工作:正如上面評論中所述的dyp,優化編譯器可能刪除了一些代碼片段,其中-O0用於模板實例化。 可能......我仍然沒有聲稱完全理解這一切。

@dyp:你為什么不發表一個全面的答案來解釋你早先的評論呢?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM