7

我用我的代碼就地析構函數,類似這樣的精簡一段代碼:C++就地析構函數編譯警告

#include <new> 
#include <stdlib.h> 

struct Node { 
}; 

int main(int, char**) { 
    Node* a = reinterpret_cast<Node*>(malloc(sizeof(Node))); 
    new(a) Node; 

    Node* b = a; 
    b->~Node(); 

    free(a); 
} 

不幸的是這給了我在Visual Studio 2015年警告,無論是在Debug和Release :

warning C4189: 'b': local variable is initialized but not referenced

它編譯罰款雖然G ++,甚至-Wall。任何想法爲什麼我得到警告?可能這是編譯器中的一個錯誤? b清楚地在b->~Node()呼叫中使用。

它也似乎當我改變的節點執行這個編譯罰款:

struct Node { 
    ~Node() { 
    } 
}; 

但據我可以說,這不應該有所作爲。

+1

嗯,我的猜測是,優化器完全拋棄了對默認析構函數的調用,然後得出結論認爲'b'永遠不會被使用。只有在編譯經過優化的版本時纔會看到此警告,或者您是否在未優化/調試版本中看到此警告? –

+0

它也在調試版本 – martinus

+0

有趣。是的,我在優化器啓用和禁用的情況下對32位和64位版本以及VS 2010,2012和2015進行了重新編譯。對我來說看起來像是一個bug,除非我還缺少一些明顯的東西。 (當然,它*是*在優化構建中消除了對析構函數的調用,事實上,它也消除了對構造函數的調用。目標代碼只調用'malloc'和'free'。) –

回答

2

在C++中沒有關於編譯器警告的標準。因此,每個編譯器都可以在任何地方提醒你,這是一個選擇問題

在你的情況下,警告確實有意義,因爲默認析構函數可能不會將視爲引用(例如:所有局部變量在其作用域的末尾被默認銷燬)。

2

Trivial destructor

類T的析構函數是平凡的,如果滿足以下所有的條件爲真:

  • 析構函數不是用戶提供的(意思是,它要麼是隱式地聲明,或明確定義爲默認第一個聲明)
  • 析構函數不是虛擬的(也就是說,基類析構函數不是虛擬的)
  • 所有直接基類都有微不足道的析構函數
  • 類類型(或類類型數組)的所有非靜態數據成員都有微不足道的析構函數。

一個微不足道的析構函數是一個不執行任何操作的析構函數。帶有瑣碎析構函數的對象不需要delete-expression,並且可以通過簡單地釋放其存儲來處理。