int main() {
int* ptr = nullptr;
delete ptr;
}
在GCC(7.2)中,生成的程序中存在一个与
operator delete
相关的call
指令。而在Clang和Intel编译器中,没有这样的指令,空指针删除完全被优化掉了(-O2
在所有情况下都是如此)。您可以在https://godbolt.org/g/JmdoJi进行测试。我想知道是否可以通过某种方式在GCC上打开这样的优化?(我的更广泛的动机源于可移动类型的自定义
swap
与std::swap
的问题,在第二种情况下,空指针删除可能代表性能损失;有关详细信息,请参见https://dev59.com/xmw15IYBdhLWcg3wv-ba#45689282。)更新:
为了澄清我的问题动机:如果我在某个类的move assignment operator和destructor中只使用
delete ptr;
而没有使用if (ptr)
守卫,则使用GCC对该类对象进行std::swap
会产生3个call
指令。这可能是一个相当大的性能损失,例如当对这些对象的数组进行排序时。此外,我可以在任何地方写
if (ptr) delete ptr;
,但我想知道这是否也会导致性能损失,因为delete
表达式也需要检查ptr
。但是,在这里,我猜编译器只会生成一个检查。另外,我真的很喜欢调用没有保护的
delete
的可能性,而且令我惊讶的是,它可能会产生不同的(性能)结果。更新
我刚刚做了一个简单的基准测试,即对调用其移动赋值运算符和析构函数中的
delete
的对象进行排序。源代码在此处:https://godbolt.org/g/7zGUvo
使用GCC 7.1和Xeon E2680v3上的-O2
标志测量的std::sort
运行时间:有一个链接代码中的错误,它比较指针,而不是指向的值。更正后的结果如下:
- 没有
if
保护:17.6 [s]40.8 [s], - 有
if
保护:10.6 [s]31.5 [s], - 有
if
保护和自定义swap
:10.4 [s]31.3 [s]。
delete
前添加显式的if
会生成什么样的代码吗? - hyde