当我使用这种 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_Enable
和 INT_Disable
函数 implement a counter 所以 INT_Enable
会做正确的事情,只在真正需要启用中断时才启用中断。所以这个 class 应该可以正确嵌套。
void func() {
InterruptGuard guard;
// ...
}
我的问题是:
当我使用此模式时,编译器是否会在此处执行 "the right thing" 并优化对象(因此此 class 实际上不会消耗内存)并内联 INT_Enable
和 INT_Disable
调用使用 InterruptGuard
class?
的函数
Compiling 与 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 , %rsp
movl $.LC0, %edi
call puts
movl $.LC1, %edi
call puts
xorl %eax, %eax
addq , %rsp
ret
有一种 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_Enable
和 INT_Disable
函数 implement a counter 所以 INT_Enable
会做正确的事情,只在真正需要启用中断时才启用中断。所以这个 class 应该可以正确嵌套。
void func() {
InterruptGuard guard;
// ...
}
我的问题是:
当我使用此模式时,编译器是否会在此处执行 "the right thing" 并优化对象(因此此 class 实际上不会消耗内存)并内联 INT_Enable
和 INT_Disable
调用使用 InterruptGuard
class?
Compiling 与 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 , %rsp
movl $.LC0, %edi
call puts
movl $.LC1, %edi
call puts
xorl %eax, %eax
addq , %rsp
ret