【问题标题】:C++ Queue::Pop function acts weird when compiled with -O1C++ Queue::Pop 函数在使用 -O1 编译时表现得很奇怪
【发布时间】:2022-06-11 01:03:19
【问题描述】:

我一直在用 C++ 编写自己的队列。 问题在于它有一个名为 Queue::Pop() 的函数,该函数调用队列中第一项的析构函数,该函数由名为 _First 的索引跟踪,然后 _First 递增,_Length 递减。 当正常编译时,它按预期执行,但是当添加 -O1 标志时,它开始表现得很奇怪并且没有正确调用对象的析构函数。 析构函数中的打印发生但 Id 未设置为 -1。 结果,当队列超出范围时,内存被 delete[] 编辑并再次调用析构函数,这是无效代码,因为如果它是文件描述符,它将被关闭两次。 这是弹出功能:

void Queue::Pop()
{
     std::destroy_at(std::addressof(Head()));
     --_Length;
     _First = (_First + 1) % Capacity();
}

T &Head()
{
    AssertEmpty();
    return _Content.Content()[_First];
}

我正在用这样的方式测试我的代码:


class Messenger
{
public:
    int Id = -1;

    Messenger() = default;
    Messenger(size_t id) : Id(id)
    {
        std::cout << Id << " Constructed" << std::endl;
    }

    Messenger(Messenger &&Other) : Id(std::move(Other.Id))
    {
        Other.Id = -1;
    }

    Messenger &operator=(Messenger &&Other)
    {
        Id = std::move(Other.Id);
        Other.Id = -1;
        return *this;
    }

    ~Messenger()
    {
        if (Id != -1)
        {
            std::cout << Id << " Destructed" << std::endl;
            Id = -1;
        }
    }
};

以及主要功能:

int main(int argc, char const *argv[])
{
    Queue<Messenger> Queue;

    Queue.Add(1);
    Queue.Add(2);

    Queue.Pop();
    Queue.Pop();

    std::cout << "Finished" << std::endl;

    return 0;
}

这里是我得到的输出:

1 Constructed
2 Constructed
1 Destructed
2 Destructed
Finished
2 Destructed
1 Destructed

如您所见,打印完成后,无需打印任何其他内容。

【问题讨论】:

  • 顺便说一句,这只发生在 gcc 而不是 clang!

标签: c++ gcc optimization memory queue


猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-03
  • 2014-02-05
  • 2013-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多