2016-11-08 32 views
13

在最近發現的一個錯誤追蹤中,我發現返回指向臨時變量成員的指針有問題。有問題的(簡體)代碼是:如何防止返回一個指向臨時變量的指針?

struct S { 
    S(int i) : i(i) {} 
    int i; 
    int* ptr() { return &i; } 
}; 

int* fun(int i) { return S(i).ptr(); } // temporary S dies but pointer lives on 

int main() { 
    int* p = fun(1); 
    return *p; // undefined 
} 

如何防止這種情況?海灣合作委員會&鐺有-Waddress-of-temporary-Wreturn-stack-address但他們似乎鬆散的軌跡,因爲ptr()充當骯髒行爲的中間人。當指針直接取它們只觸發:

int* fun(int i) { return &S(i).i; } // rightly fails to compile 

我的項目還採用cppcheck在持續集成,但它也可以把它撿起來(凸起here)。

哪個靜態分析工具可以防止這類錯誤?

編輯:從版本6.1.0開始,GCC確實會提取它,並且-Wreturn-local-addr和(令人驚訝的)-O2開啓。

+3

如果你用'-O2'編譯,gcc會捕獲這個bug:http://melpon.org/wandbox/permlink/KaXY4ktTM1vMNTiX – krzaq

+11

「如何防止這個?」只有一個解決方案 - 停止使用原始指針 – Slava

+1

@krzaq'-O2'與它無關,但GCC的版本(從6.1.0開始檢測)。我不能使用新的GCC,但這是一個很好的說法,可以讓我們的維護人員切換到更新的版本:) –

回答

3

我是Cppcheck的開發者。

我的項目還在持續集成中引入了cppcheck,但它也無法提取它。

有趣的bug。這是cppcheck想警告的錯誤。我們有一些相關的檢查,但不幸的是這個滑落。

由於cppcheck的正則表達式本質上並不令人驚訝。

我個人不理解爲什麼有人說cppcheck是一個正則表達式工具。

它使用AST,上下文敏感的價值流分析等來檢測錯誤。 GCC和Clang也是如此。 Cppcheck有時聲稱是一個正則表達式工具,但GCC和Clang不是。

+1

供參考:關於這個問題的票已經創建http://trac.cppcheck.net/ticket/7812 – orbitcowboy

+3

我承認我沒有查看cppcheck內部,並可能得到的印象是它是基於正則表達式的自定義規則的方式定義。我從這個問題中刪除了這個評論,而不是擴散錯誤的信息。 –

相關問題