当我使用这种 RAII 风格的模式时,对象本身是否被优化了?

Is the object itself optimized out when I use this RAII-style pattern?

有一种 RAII 风格的 C++ 模式,它通过创建一个没有成员的 class 并依赖于 class 的构造函数和析构函数(以及当函数 returns) 时自动调用析构函数。例如,标准 std::lock_guard 实现了这个模式。

我正在对 EFM32 ARM Cortex-M 微控制器进行编程,并想出了这个 class,它使用了类似的风格:

#include <em_int.h>

class InterruptGuard final {

public:

    explicit inline InterruptGuard() {
        INT_Disable();
    }

    InterruptGuard(const InterruptGuard &other) = delete;

    InterruptGuard(const InterruptGuard &&other) = delete;

    inline ~InterruptGuard() {
        INT_Enable();
    }

    InterruptGuard &operator=(const InterruptGuard &other) = delete;

    InterruptGuard &operator=(const InterruptGuard &&other) = delete;

};

因此,如果我想在具有多个 return 语句的函数内禁用中断,我可以确保它们将被重新启用,而不必担心在每个 [=] 时显式重新启用它们39=]声明。

注意:INT_EnableINT_Disable 函数 implement a counter 所以 INT_Enable 会做正确的事情,只在真正需要启用中断时才启用中断。所以这个 class 应该可以正确嵌套。

void func() {
    InterruptGuard guard;

    // ...
}

我的问题是:

当我使用此模式时,编译器是否会在此处执行 "the right thing" 并优化对象(因此此 class 实际上不会消耗内存)并内联 INT_EnableINT_Disable 调用使用 InterruptGuard class?

的函数

Compilingg++ -std=c++1y -O3 -Werror -Wextra(gcc 版本 5.3.0)此代码:

#include <cstdio>

class InterruptGuard final {

public:

    explicit inline InterruptGuard() {
        printf("enable\n");
    }

    InterruptGuard(const InterruptGuard &other) = delete;

    InterruptGuard(const InterruptGuard &&other) = delete;

    inline ~InterruptGuard() {
        printf("disable\n");
    }

    InterruptGuard &operator=(const InterruptGuard &other) = delete;

    InterruptGuard &operator=(const InterruptGuard &&other) = delete;

};

int main()
{
    InterruptGuard i;
}

和此代码:

#include <cstdio>

int main()
{
  printf("enable\n");
  printf("disable\n");
}

在两种情况下给出相同的程序集:

.LC0:
        .string "enable"
.LC1:
        .string "disable"
main:
        subq    , %rsp
        movl    $.LC0, %edi
        call    puts
        movl    $.LC1, %edi
        call    puts
        xorl    %eax, %eax
        addq    , %rsp
        ret