Оптимизируется ли сам объект при использовании этого шаблона в стиле RAII?

Существует шаблон C ++ в стиле RAII, который реализует владение на основе области путем создания класса, который не имеет члена, и полагается на конструктор и деструктор класса (и тот факт, что деструктор автоматически вызывается при возврате функции). Например, стандарт std::lock_guard реализует этот шаблон.

Я программирую микроконтроллер ARF Cortex-M EFM32 и придумала этот класс, который использует похожий стиль:

#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;

};

Поэтому, если я хочу отключить прерывания внутри функции с помощью нескольких операторов возврата, я могу убедиться, что они будут включены повторно, и я не буду беспокоиться об их явном включении при каждом операторе возврата.

Обратите внимание INT_Enable а также INT_Disable функции реализовать счетчик так INT_Enable будет делать правильные вещи и включать прерывания только тогда, когда они действительно должны быть включены. Так что этот класс должен быть правильно вложенным.

void func() {
InterruptGuard guard;

// ...
}

Мой вопрос:

Когда я использую этот шаблон, собирается ли компилятор делать «правильные вещи» здесь и оптимизировать объект (так, чтобы этот класс фактически не потреблял память) и просто вставлять INT_Enable а также INT_Disable вызовы функции, которая использует InterruptGuard учебный класс?

2

Решение

составление с g++ -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    $8, %rsp
movl    $.LC0, %edi
call    puts
movl    $.LC1, %edi
call    puts
xorl    %eax, %eax
addq    $8, %rsp
ret
5

Другие решения

Других решений пока нет …