启用优化的g ++和clang ++的奇怪行为[重复]

Posted

技术标签:

【中文标题】启用优化的g ++和clang ++的奇怪行为[重复]【英文标题】:Odd behaviour of g++ and clang++ with enabled optimization [duplicate] 【发布时间】:2018-06-07 17:34:30 【问题描述】:

这是我的程序:

打印.hpp:

#pragma once

#include <iostream>

template<size_t p>
void print()

  std::cout << "" << __FILE__ << "" <<  __LINE__ << "" << std::endl;
  exit(0);

打印.cpp:

#include "print.hpp"

template<>
void print<13>()

  std::cout << "Unlucky." << std::endl;

main.cpp:

#include <iostream>
#include "print.hpp"

int main()

  std::cout << "Started." << std::endl;
  print<13>();
  std::cout << "Exiting." << std::endl;

当我用g++ main.cpp print.cpp -O0 -std=c++11 &amp;&amp; ./a.out 编译它时,它工作正常(输出为:

Started.
Unlucky.
Exiting.

)。 但是,如果我用g++ main.cpp print.cpp -O1 -std=c++11 &amp;&amp; ./a.out 编译它,它会给我一个输出分段错误:

Started.
Unlucky.
Speicherzugriffsfehler //German for memory access error

与 clang++ 几乎相同,没有优化它就可以正常工作 并使用 -O1 或更高版本输出:

Started.
Unlucky.
./print.hpp8

为什么会这样?

【问题讨论】:

我没有看到任何打印“Hi”的代码您确定使用了显示的代码吗? 您可以使用g++ -g -O1 -std=c++11 main.cpp print.cpp 编译并使用gdb 调试器(您可以同时使用-g-O1 @Slava 已更正。谢谢。 您的程序格式不正确,请参阅欺骗中的详细信息 【参考方案1】:

您需要在 .hpp 文件中声明模板特化。

template<size_t p>
void print()

  std::cout << "" << __FILE__ << "" <<  __LINE__ << "" << std::endl;
  exit(0);


// Declare the specialization.
template<> void print<13>();

如果没有 .hpp 文件中的声明,我会收到 g++ 6.4.0 的链接器错误。

.../Local/Temp/cctCC5MK.o:print.cc:(.text+0x0): multiple definition of `void print<13ul>()'
.../Local/Temp/ccgodRUG.o:socc.cc:(.text$_Z5printILm13EEvv[_Z5printILm13EEvv]+0x0): first defined here
collect2: error: ld returned 1 exit status

我不确定您如何在没有声明的情况下成功构建程序。

【讨论】:

您的回答没有回答“为什么”位。 好吧,我在 x86_64 Linux 上使用了相同版本的 g++,它与我发布的代码完全相同。 @DariusDuesentrieb,我不知道该怎么解释。

以上是关于启用优化的g ++和clang ++的奇怪行为[重复]的主要内容,如果未能解决你的问题,请参考以下文章

g++-8 和更早版本之间的奇怪行为

嵌套类中 g++ 和 clang++ 之间的不同行为

Linux 上 fortran 代码的 Intel Vtune 奇怪行为

HystrixCommand 的奇怪行为

带有非类型参数的奇怪模板实例化错误

用 g++ 编译的奇怪代码