gpt4 book ai didi

c++ - 为什么C++优化器在删除相同的指针时使用不同的删除

转载 作者:行者123 更新时间:2023-12-03 06:57:47 25 4
gpt4 key购买 nike

当gcc 7.3优化我从google测试库中使用的某些代码时,我遇到了一个奇怪的问题。该问题已在Google测试中解决,但我仍然对这个问题感到困惑:出于某种原因,是否存在更多具有相同签名的全局删除运算符?
我的代码在这里:https://godbolt.org/z/86Eevc,更有趣的是,对于-O0,所有call指令都使用相同的删除地址。有了-O3,一切开始变得有趣起来。 (godbolt上的链接在选中“编译为二进制”时很有用,这样您就可以看到为调用参数生成的地址)。
我的类(DeleteInside)派生自具有虚拟表的类,该类具有执行delete this;的deleteMe()方法。如果我在全局范围内声明DeleteInside *ptr = nullptr;,然后在主函数中调用delete ptr;,则delete运算符的地址与使用ptr->deleteMe();时调用的delete不同。
谁能解释?

static int timesDeleted = 1;
class DeleteBase
{
public:
virtual ~DeleteBase() {
timesDeleted += 1;
}
};
class DeleteInside
{
int _val;
public:
~DeleteInside() {
timesDeleted = (timesDeleted * _val);
}
bool doSomething() {
return false;
}

__attribute__((noinline)) void deleteMe() const {
timesDeleted += 1;
delete this;
}
};
DeleteInside *delInside = nullptr;
int main(int argc, char *argv[]) {

//delete delInside;
delInside->deleteMe();
delete delInside;
return timesDeleted;
}

最佳答案

解释很简单:您调用未定义的行为(取消引用空指针),因此任何事情都可能发生。如您所知,这种事情的一个明显迹象是优化级别会影响结果。
在这两种情况下,您看到的地址都是垃圾。至于它们为什么完全不同的原因,您需要一个了解GCC 7.3如何处理这种未定义行为的特定情况的人,但是出于所有意图和目的,所有有用的C++解释都将停留在“它是未定义的行为”上。
如果我不得不猜测,在这种情况下,vtable及其优化方式可能与它有关。

关于c++ - 为什么C++优化器在删除相同的指针时使用不同的删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64257564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com