2016-08-04 33 views
0

考慮下面的代碼:的Visual Studio 2013不正確地清理在try/catch塊

#include <functional> 
#include <memory> 
#include <iostream> 

void FuncA(){} 

void FuncB(std::function<void()> callback) { 
    try { 
    // Do something here... 
    } 
    catch(...) { 
    return FuncA(); 
    } 

    // Do something else... 
} 

void main() { 
    auto foo = std::make_shared<bool>(); 
    auto callback = [foo]{}; 

    std::cout << foo.use_count() << std::endl; 
    FuncB(callback); 
    std::cout << foo.use_count() << std::endl; 
} 

當的Visual Studio 2013下編譯這一點,FuncB生成的彙編代碼()不清除回調正確的,這會將foo的引用計數增加1,並導致內存泄漏。

有一件事我沒有注意到,就是如果我改變FuncB是...

void FuncB(std::function<void()> callback) { 
    try { 
    // Do something here... 
    } 
    catch(...) { 
    FuncA(); 
    return; 
    } 

    // Do something else... 
} 

......然後一切按預期工作和之前的數量和所追求的一樣。

我正在使用VS2013版本12.0.31101.00更新4 編譯器版本是18.00.31101 x64。

有沒有人有一個想法是什麼造成這個問題?

+0

看起來像尾調用優化可能已經在有問題的版本中搞砸了。 –

+0

在最新的VS2015社區中是否出現同樣的問題?這將是一個非常有說服力的測試。 – gdc

+0

[按預期工作](http://rextester.com/VRNMO51268)與VC15,它的價值。 –

回答

0

我想在這兩個MSVC 2013更新你的榜樣4,MSVC 2015年更新2和Coliru(http://coliru.stacked-crooked.com/

在MSVC 2013我得到的輸出:

2 
3 

雖然MSVC 2015年我得到了輸出:

2 
2 

Coliru證實MSVC 2015年的產量,因此它似乎是一個錯誤在MSVC 2013年

我要麼如果有可能升級編譯器,或者使用:

FuncA(); 
return; 

我認爲這有點奇怪返回void反正寧願在下一行return語句。 (但這只是我的意見。)

+0

實際上,您可以使用返回整數的函數,但仍然會遇到相同的行爲。 – maxag

+0

我注意到,如果'try {}'塊包含'return;'語句,則不會發生此問題。這對你也是如此嗎? –

相關問題