Visual Studio 2013无法在try / catch块中正确清理

时间:2016-08-04 16:43:50

标签: visual-studio c++11 visual-c++ visual-studio-2013

请考虑以下代码:

#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。

有谁知道造成这个问题的原因是什么?

1 个答案:

答案 0 :(得分:0)

我在MSVC 2013 Update 4,MSVC 2015 Update 2和Coliru(http://coliru.stacked-crooked.com/)中尝试了您的示例

在MSVC 2013中,我得到了输出:

2
3

在MSVC 2015中,我得到了输出:

2
2

Coliru确认了MSVC 2015的输出,因此它似乎是MSVC 2013中的一个错误。

如果可能,我会升级编译器,或者使用:

FuncA();
return;

我认为返回void有点奇怪,无论如何都更喜欢下一行的return语句。 (但这只是我的意见。)