2016-04-24 28 views
2

有一種RAII風格的C++模式,它通過創建一個沒有成員並依賴於類的構造函數和析構函數的類(以及在函數返回時自動調用析構函數的事實)來實現基於作用域的所有權。例如,標準std::lock_guard實現了這種模式。當我使用這種RAII風格的圖案時,對象本身是否被優化了?

我編程的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語句在函數內部中斷,I可以確保他們將被重新啓用,而不必擔心在每個退貨聲明中明確重新啓用它們。

注:INT_EnableINT_Disable功能implement a counter所以INT_Enable會做正確的事,只有當他們真正需要啓用允許中斷。所以這個類應該可以正確嵌套。

void func() { 
    InterruptGuard guard; 

    // ... 
} 

我的問題是:

當我使用這個模式,是編譯器會做「正確的事」在這裏,優化了對象(所以沒有記憶由此類實際消耗)並且將內聯函數INT_EnableINT_Disable調用到使用InterruptGuard類的函數中?

+1

大概。唯一可以確定的方法是查看生成的代碼。 –

+0

「InterruptGuard」實際上沒有佔用內存,那麼應該優化哪些內容? –

+0

@πάνταῥεῖ'爲什麼? sizeof(InterruptGuard)'必須是非零的,你可以把'guard'的地址。 –

回答

5

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

這裏是[arm版本](https:// godbolt。 org/g/GiHFR4)。請注意,當啓用/禁用中斷時,此RAII無法控制,並讓編譯器找出它。在很多情況下,這會增加中斷延遲。 RAII非常適合執行時間無關緊要的護理。您可以在需要禁用中斷的情況下通過模塊範圍來解決此問題;該對象應該只存在於該塊中。 –

相關問題