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

Is C++ compiler allowed to optimize out unreferenced local objects

我使用下面的class在某个函数的开头自动设置等待光标,并在函数return秒时重置光标。

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

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

如果编译器优化掉未引用的 WaitCursorSetter 对象,这将不起作用。我的问题是,是否允许编译器优化这个对象?

如果您能观察到任何不同,则不允许编译器删除该对象。

在这种情况下,constructor/destructor 有副作用,因此编译器不会删除它们。

将效果委托给本地基于堆栈的对象 construction/destruction 的想法经常被使用;例如:

{
    Locker L(my_lock);
    ...
}

这样 ... 中的代码将在持有锁的情况下执行,并且当您出于任何原因离开作用域时(刚离开块,执行 return or and if if exception while inside).

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

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

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

看到这一点

If a variable with automatic storage duration has initialization or a destructor with side effects, it shall not be destroyed before the end of its block, nor shall it be eliminated as an optimization even if it appears to be unused, except that a class object or its copy/move may be eliminated as specified in 12.8.