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

时间:2015-06-02 12:57:50

标签: c++ cmake

我编写了一个使用cmake绑定的C ++程序 并在Debian机器上运行。我很高兴地说所有已知的主要错误都是 纠正了,我觉得我已经准备好了。

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

一直到

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

我做到了这一点,突然间我的项目中有一个模板化的课程 (在某些头文件中天真地声明并为所有用例定义 在一些单独的.cpp中打破了一个" undefined"错误 在联系期间。

对这个论坛的一些研究产生了这样的线索: Why can templates only be implemented in the header file? 我相信我看到Luc在他的着名答案中正在开车 at:编译器 实际上'写代码'对于模板化类的每个所需版本 (即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。)关于评论问题&#34;如何定义用例?&#34;:让我们利用这个在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行开始。

1 个答案:

答案 0 :(得分:2)

我的问题已经解决,dyp与他/她的评论最接近。神奇的词是&#34;显式模板instanciation&#34;可以在这里找到:http://www.cplusplus.com/forum/articles/14272/

我没有使用定义混乱我的头文件。我也没有将像 #include&#34; some.cpp&#34; 这样的代码添加到标题中,我认为这相同。相反,我添加了行

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

在landscape.cpp中的定义下,并且能够使用-O2进行编译。

根据Why can templates only be implemented in the header file?我虽然不能使用除了数字和正方形之外的任何其他东西(这很适合我)。

至于为什么-O0工作:正如上面评论中所述的dyp,优化编译器可能删除了一些代码片段,其中-O0用于模板实例化。可能......我仍然没有声称完全理解它。

@dyp:为什么不发表这个问题的综合答案来解释你之前的评论呢?