在 IF ELSE 的链中使用 goto 有什么特别之处
what so special about a use of goto in a chain of if else
我正在看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 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_
语句,代码大小显著减小。
这个伴随的演示文稿可能会证明是有用的阅读(虽然很简洁)。
下面的代码不是更容易理解吗?编译器产生的汇编指令也更少:
~SingleThreadPtr() {
if (c_) {
if (--*c_ != 0) {
return;
}
delete c_;
}
delete p_;
}
组装说明:
test rcx,rcx
je wmain+0C8h (013F3813D8h)
dec dword ptr [rcx]
jne wmain+0D5h (013F3813E5h)
call qword ptr [__imp_operator delete (013F3831E8h)]
mov rcx,qword ptr [p_ (013F385708h)]
call qword ptr [__imp_operator delete (013F3831E8h)]
原始代码如下:
~SingleThreadPtr() {
if(!c_) {
soSueMe: delete p_;
} else if(--*c_ == 0) {
delete c_;
goto soSueMe;
}
}
生成以下程序集代码:
test rcx,rcx
je wmain+0A5h (013F3813B5h)
dec dword ptr [rcx]
jne wmain+0B9h (013F3813C9h)
call qword ptr [__imp_operator delete (013F3831E8h)]
mov rcx,qword ptr [p_ (013F385708h)]
call qword ptr [__imp_operator delete (013F3831E8h)]
mov rcx,qword ptr [c_ (013F385710h)]
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 什么时候调用组成单元对象的析构函数
- #定义c-预处理器常量..我做错了什么
- 努力将整数转换为链表。不知道我在这里做错了什么
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 什么时候在C++中返回常量引用是个好主意
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- C++避免重复声明的语法是什么
- c++库的公共头文件中应该包含什么
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- ifstream什么都没读
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 IF ELSE 的链中使用 goto 有什么特别之处
- 使用什么而不是Goto语句