为什么使用NOExcept时Xcode生成更多指令

发布于 2025-02-13 18:58:06 字数 1654 浏览 2 评论 0原文

这是一个琐碎的程序,使用C ++ 11在Intel Mac上编辑,

#include <iostream>

void show() //noexcept
{
   std::cout << "Hello, World!\n";
}

int main(int argc, const char * argv[]) 
{
   show();
   return 0;
}

我一直在检查“ NOEXCEPT”在调试模式和发布(优化)模式下使用“ NOEXCEPT”时的代码生成差。

在调试模式下,如果没有NOExcept预选赛,我会获得以下显示功能的说明:

0x100003280 <+0>:  pushq  %rbp
0x100003281 <+1>:  movq   %rsp, %rbp
0x100003284 <+4>:  movq   0xd75(%rip), %rdi         ; (void *)0x00007fff96d36760: std::__1::cout
0x10000328b <+11>: leaq   0xcc2(%rip), %rsi         ; "Hello, World!\n"
0x100003292 <+18>: callq  0x100003e2c               ; symbol stub for: std::__1::basic_ostream<char.....
0x100003297 <+23>: popq   %rbp
0x100003298 <+24>: retq   

非常明显 - 创建堆栈帧,设置呼叫cout,用堆栈框架完成并返回。

但是,如果我删除“ noexcept”,那么我会得到以下内容:

0x100003240 <+0>:  pushq  %rbp
0x100003241 <+1>:  movq   %rsp, %rbp
0x100003244 <+4>:  subq   $0x10, %rsp
0x100003248 <+8>:  movq   0xdb1(%rip), %rdi         ; (void *)0x00007fff96d36760: std::__1::cout
0x10000324f <+15>: leaq   0xcee(%rip), %rsi         ; "Hello, World!\n"
0x100003256 <+22>: callq  0x100003e0c               ; symbol stub for: std::__1::basic_ostream<char....
0x10000325b <+27>: jmp    0x100003260               ; <+32> at main.cpp:14:1
0x100003260 <+32>: addq   $0x10, %rsp
0x100003264 <+36>: popq   %rbp

请注意额外的减法(第三行)和反向添加(第二行)。更好奇的是JMP指令,它跳到下一行。

问题

  1. 为什么要使用Noexcept生成额外的代码 - 我认为如果您保证堆栈不需要解开
  2. 该JMP指令的目的是什么?

提前致谢

Here's a trivial program, compiled on Intel Mac using C++11

#include <iostream>

void show() //noexcept
{
   std::cout << "Hello, World!\n";
}

int main(int argc, const char * argv[]) 
{
   show();
   return 0;
}

I've been examining the difference in code generation when 'noexcept' is used or not used both in debug mode and release (optimized) mode.

In debug mode, without the noexcept qualifier, I get the following instructions for the show function:

0x100003280 <+0>:  pushq  %rbp
0x100003281 <+1>:  movq   %rsp, %rbp
0x100003284 <+4>:  movq   0xd75(%rip), %rdi         ; (void *)0x00007fff96d36760: std::__1::cout
0x10000328b <+11>: leaq   0xcc2(%rip), %rsi         ; "Hello, World!\n"
0x100003292 <+18>: callq  0x100003e2c               ; symbol stub for: std::__1::basic_ostream<char.....
0x100003297 <+23>: popq   %rbp
0x100003298 <+24>: retq   

Very obvious - create stack frame, set up the call to cout, finish with stack frame and return.

However, if I uncomment 'noexcept' then I get the following:

0x100003240 <+0>:  pushq  %rbp
0x100003241 <+1>:  movq   %rsp, %rbp
0x100003244 <+4>:  subq   $0x10, %rsp
0x100003248 <+8>:  movq   0xdb1(%rip), %rdi         ; (void *)0x00007fff96d36760: std::__1::cout
0x10000324f <+15>: leaq   0xcee(%rip), %rsi         ; "Hello, World!\n"
0x100003256 <+22>: callq  0x100003e0c               ; symbol stub for: std::__1::basic_ostream<char....
0x10000325b <+27>: jmp    0x100003260               ; <+32> at main.cpp:14:1
0x100003260 <+32>: addq   $0x10, %rsp
0x100003264 <+36>: popq   %rbp

Note the extra subtraction (third line) and the reverse addition (second last line). More curious is the jmp instruction which just jumps to the next line.

Questions

  1. Why is extra code being generated with noexcept - I thought there would be less if you're guaranteeing that the stack doesn't need to be unwound
  2. What's the purpose of that jmp instruction?

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文