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

问题描述

当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;
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)