是否允许C ++编译器优化未引用的本地对象

时间:2015-01-02 11:47:27

标签: c++ qt optimization

我使用以下类在某个函数的开头自动设置等待光标,并在函数返回时重置光标。

class WaitCursorSetter
{
public:
    WaitCursorSetter() {QApplication::setOverrideCursor(Qt::WaitCursor);}
    virtual ~WaitCursorSetter() {QApplication::restoreOverrideCursor();}
};

我在函数开始时创建一个本地WaitCursorSetter对象。由于等待游标在对象的析构函数中被重置,因此当函数返回并且对象超出范围时,我不必在方法中的每个return语句之前重置游标,因为析构函数被调用。

如果编译器优化了未引用的WaitCursorSetter对象,则不起作用。我的问题是,编译器是否允许优化此对象?

3 个答案:

答案 0 :(得分:6)

不允许编译器优化掉析构函数或初始化具有副作用的自动对象,我们可以通过转到草案标准部分3.7.3来看到这一点:

  

如果具有自动存储持续时间的变量已初始化或a   具有副作用的析构函数,在结束前不得销毁   它的块,即使它也不会作为优化被消除   似乎未使用,除了类对象或其复制/移动可能   按照12.8的规定予以淘汰。

答案 1 :(得分:2)

这样做非常安全。事实上,在实践RAII时,它是一种经常使用的技术。编译器不会优化任何具有非平凡构造函数或析构函数的局部变量。查看What is a non-trivial constructor in C++

为了避免关于未使用的局部变量的编译器警告,您可以使用 Q_UNUSED 宏。

答案 2 :(得分:0)

如果您可以观察到任何不同的情况,则不允许编译器删除该对象。

在这种情况下,构造函数/析构函数有副作用,因此编译器不会删除它们。

经常使用将效果委托给构造/销毁本地基于堆栈的对象的想法;例如:

{
    Locker L(my_lock);
    ...
}

这样...中的代码将在保持锁定的情况下执行,当您因任何原因离开作用域时,锁定将自动释放(只是离开块,执行{{1或者,如果在内部抛出异常。)