c++ - 在 if else 链中使用 goto 有什么特别之处

标签 c++ optimization

我正在观看 Alexandrescu 的视频,他的代码片段如下:

 // an example implementation of a single threaded shared_ptr
 ~SingleThreadPtr() { 
    if(!c_) {
       soSueMe: delete p_;
    } else if(--*c_ == 0) {
       delete c_;
       goto soSueMe;
    }
 }

这里是 https://youtu.be/Qq_WaiwzOtI?t=36m44s .他说,“我使用我著名的 'goto soSueMe' 构造”,并说“尝试在没有 goto 的情况下编写这个,[..] 你会发现它很困难”。

这有什么难的?下面是不是一样,显然不难,而且更易读:

 // an example implementation of a single threaded shared_ptr
 ~SingleThreadPtr() { 
    if(!c_) {
       delete p_;
    } else if(--*c_ == 0) {
       delete c_;
       delete p_;
    }
 }

或者甚至不一样(从而首先加强了反对 goto 的论点)?这里发生了什么样的黑客黑魔法巫术?

最佳答案

这里的重点是 shared_ptr 析构函数被相对频繁地调用,并且通常是内联的,这是一种减少内联析构函数大小的尝试(因为 goto 比 delete 调用小得多)。

例如,编译时的析构函数调用 delete p_ 可能类似于:

LBB5_8:
    movq    -16(%rbp), %rax         ## 8-byte Reload
    movq    (%rax), %rcx
    cmpq    $0, %rcx
    movq    %rcx, -24(%rbp)         ## 8-byte Spill
    je  LBB5_4
    movq    -24(%rbp), %rax         ## 8-byte Reload
    movq    %rax, %rdi
    callq   __ZdlPv                 
LBB5_4:

(其中 callq __ZdlPv 是最终被调用的底层对象析构函数)。

goto 看起来就像这样:

LBB5_8:
    jmp LBB5_2

因此,通过分支而不是重复 delete p_ 语句,代码大小显着减少。

This accompanying presentation可能会被证明是有用的阅读(虽然很简洁)。

关于c++ - 在 if else 链中使用 goto 有什么特别之处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35733307/

相关文章:

python - 为什么 CVXOPT 会给出这种非线性网络流优化的排名误差?

c# - 尝试从 setpixel/getpixel 进行优化

c++ - 编译器何时会优化 C/C++ 源代码中的汇编代码?

jquery - 延迟加载 Reddit 小部件

C++ qt基础问题

c++ - 函数模板和模棱两可的模板参数

c++ - 如何将文件中的字符串和整数放入多维数组?

c++ -//! [0] 在 Qt 源代码中

c++ - 需要帮助确定输入的字符是符号、数字还是字母

sql - 左联接是我想要的,但是速度很慢?