gpt4 book ai didi

c++ - 未使用的析构函数会被优化掉吗?

转载 作者:太空宇宙 更新时间:2023-11-04 15:54:09 26 4
gpt4 key购买 nike

假设 MyClass 使用默认析构函数(或没有析构函数),并且此代码:

MyClass *buffer = new MyClass[i];
// Construct N objects using placement new
for(size_t i = 0; i < N; i++){
buffer[i].~MyClass();
}
delete[] buffer;

有没有优化器可以消除这个循环?

此外,我的代码是否有任何方法可以检测 MyClass 是否使用空/默认构造函数?

编辑:对我糟糕的代码感到抱歉。我认为现在这是正确的..

最佳答案

调用析构函数的正确语法是

template<typename T>
void destruct(T& x)
{
x.~T(); // call destructor on x
}

// The below is valid even though ints do not have destructors
int x;
destruct(x);

该语法对像 int 这样的类型有效(当作为模板参数传递时),但它是一个空操作(什么都不做),因此模板代码如 std::vector<T> 中的代码对其内容调用析构函数是有效的。

IMO 编译器应该可以直接看到循环内容包含空操作,因此整个循环本身没有副作用,因此删除整个循环。现代编译器具有非常复杂的优化器,应该能够删除无效的代码。如果编译器没有删除冗余循环,它会在 vector<int> 的析构函数中发出冗余代码。 !没有为 int 的析构函数发出代码,因此只会有一个空循环遍历元素,什么都不做。我敢肯定任何理智的优化器都会删除整个循环。

当然,如果您在一个确实在其析构函数中工作的类上调用析构函数,则仍必须调用该类,并且仍将存在循环(受其他相关优化的影响,例如展开)。

另一个基于副作用的优化的简单例子是这样的代码:

for (int i = 0; i < 1000000; ++i)
; // just count up i, no statement (same as no-op)

cout << i;

可能会被优化为简单地打印常量 1000000 而不进行任何处理,因为编译器足够聪明,知道整体的副作用是 i。变成一百万并打印出来。这是优化器所做的一些令人印象深刻的事情的基础,所以不用担心,它会做得很好。如果您好奇,请检查优化构建中的输出程序集,看看到底发生了什么。

关于c++ - 未使用的析构函数会被优化掉吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2630406/

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