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

时间:2016-04-24 15:23:23

标签: c++ arm microcontroller raii cortex-m

有一种RAII风格的C ++模式,它通过创建一个没有成员并依赖于类的构造函数和析构函数的类来实现基于范围的所有权(以及在函数时自动调用析构函数的事实)回报)。例如,标准std::lock_guard实现了这种模式。

我正在编程一个EFM32 ARM Cortex-M微控制器,并提出了这个使用类似风格的类:

#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语句的函数内禁用中断,我可以确保它们将重新启用,而不必担心在每个return语句中显式重新启用它们。

注意:INT_EnableINT_Disable函数implement a counter因此INT_Enable将做正确的事情,并且只在真正需要启用时启用中断。所以这个类应该是可以正确嵌套的。

void func() {
    InterruptGuard guard;

    // ...
}

我的问题是:

当我使用这种模式时,编译器是否会做正确的事情&#34;在这里并优化对象(这样该类实际上不消耗任何内存)并且只是内联INT_EnableINT_Disable对使用InterruptGuard类的函数的调用?

1 个答案:

答案 0 :(得分:5)

带有g++ -std=c++1y -O3 -Werror -Wextra(gcc版本5.3.0)的

Compiling此代码:

#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    $8, %rsp
        movl    $.LC0, %edi
        call    puts
        movl    $.LC1, %edi
        call    puts
        xorl    %eax, %eax
        addq    $8, %rsp
        ret