如何让 GCC 用非平凡的 const/dest 实例化一个类实例?

Posted

技术标签:

【中文标题】如何让 GCC 用非平凡的 const/dest 实例化一个类实例?【英文标题】:How do I make GCC instantiate a class instance with non-trivial const/dest? 【发布时间】:2011-04-16 14:50:49 【问题描述】:

我正在实现一个分析器。我想使用 Constructor/Destructor 习惯用法来跟踪我何时进入/退出函数。

我的代码大致如下:

class Profile

   Profile(void);   //Start timing
  ~Profile(void);   //Stop timer and log
;
//...
Game::Game(void) : m_Quit(false)

  Profile p();
  InitalizeModules();
  //...

但是,当我运行它时,没有调用构造函数和析构函数。即使我反汇编,也没有对 Profile::Profile() 的引用。我知道标准规定编译器不能优化具有非平凡构造函数的实例。

编译器或链接器的命令行上没有优化标志。

我也尝试指定属性((使用)),但无济于事。

这是反汇编:

(gdb) disassemble Ztk::Game::Game
Dump of assembler code for function Ztk::Game::Game():
   0x00000000004cd798 <+0>:     push   %rbp
   0x00000000004cd799 <+1>:     mov    %rsp,%rbp
   0x00000000004cd79c <+4>:     push   %r12
   0x00000000004cd79e <+6>:     push   %rbx
   0x00000000004cd79f <+7>:     sub    $0x30,%rsp
   0x00000000004cd7a3 <+11>:    mov    %rdi,-0x38(%rbp)
   0x00000000004cd7a7 <+15>:    mov    -0x38(%rbp),%rax
   0x00000000004cd7ab <+19>:    mov    %rax,%rdi
   0x00000000004cd7ae <+22>:    callq  0x4cdc6a <Ztk::Highlander<Ztk::Game, int>::Highlander()>
   /**   CALL SHOULD BE HERE   **/
   0x00000000004cd7b3 <+27>:    mov    -0x38(%rbp),%rax
   0x00000000004cd7b7 <+31>:    movb   $0x0,(%rax)
   0x00000000004cd7ba <+34>:    callq  0x4e59f0 <Ztk::InitializeModules()>

确实有代码生成并链接到可执行文件中

(gdb) disassemble Ztk::Profile::Profile(void)
Dump of assembler code for function Ztk::Profile::Profile():
   0x0000000000536668 <+0>:     push   %rbp
   0x0000000000536669 <+1>:     mov    %rsp,%rbp
   0x000000000053666c <+4>:     sub    $0x20,%rsp
   0x0000000000536670 <+8>:     mov    %rdi,-0x18(%rbp)
   0x0000000000536674 <+12>:    mov    0x8(%rbp),%rax
   0x0000000000536678 <+16>:    mov    %rax,-0x8(%rbp)
   0x000000000053667c <+20>:    mov    -0x8(%rbp),%rax
   0x0000000000536680 <+24>:    mov    %rax,%rsi
   0x0000000000536683 <+27>:    mov    $0x802440,%edi
   0x0000000000536688 <+32>:    callq  0x5363ca <Ztk::Profiler::FindNode(void*)>

【问题讨论】:

如果对象是寻找瓶颈,很多人都想按照你想要的方式来做(记录例程进入/退出),但是有一个更好的方法——堆栈采样。 Here's an explanation. Zoom 是一位备受推崇的商业分析器。这个概念可能有点曲折,但实际上非常简单。 【参考方案1】:
Profile p();

您在这里所做的是声明了一个名为 p 的函数,它返回一个 Profile 类型的对象。你想要的是这样的:

Profile p;

【讨论】:

爱上最令人头疼的 C++ 解析 :) arstechnica.com/civis/viewtopic.php?f=20&t=767929 哦!一定是这样的!我习惯于将这个习惯用法与带参数的构造函数一起使用,等我回到我的 GCC 环境时再试试。

以上是关于如何让 GCC 用非平凡的 const/dest 实例化一个类实例?的主要内容,如果未能解决你的问题,请参考以下文章

如何让 msys 识别 gcc?

Centos6.9安装部署nginx服务器

如何让 conda 使用自己的 gcc 版本?

每个平凡人心中都有一个不平凡的世界,让Map和Set带你跨过山和大海,也穿过人山人海

如何让 gcc 为 gprof 生成信息?

如何让 GCC 使用不同的标准库?