[英]C++ union struct with struct member works on Clang and MSVC but not GCC
[英]c++: MSVC vs. GCC+CLANG: Handling lambdas capturing class member variables, what is the correct approach?
考慮以下代碼段看起來非常無辜:
#include <functional>
#include <iostream>
#include <list>
#include <memory>
struct foo;
std::list<std::weak_ptr<foo>> wptrs;
std::function<void()> global_func;
struct foo {
int &a;
foo(int &a) : a{ a } { }
~foo() {
global_func = [&] {
wptrs.remove_if([](auto &x) { return x.expired(); });
std::cout << "a= " << a << std::endl;
};
}
};
int main() {
int a = 5;
auto ptr = std::make_shared<foo>(a);
wptrs.emplace_back(ptr);
ptr = nullptr; // object is destroyed here
global_func();
return 0;
}
當我第一次遇到MSVC(Visual Studio 2017)上的問題時,我正在使用TCP / IP服務器,該服務器嘗試清理連接對象的weak_ptr
列表。 連接對象通過調用weak_ptr<T>::expired()
來調度lambda以清除連接的weak_ptr
列表。 之前我很高興,因為在使用clang-6.0 +或g ++ - 7+編譯時,一切都工作正常。 然后,我必須使用MSVC並在調用destruct時收到Read Access違規。 我很震驚,並試圖產生一個表現出同樣問題的最小例子。 上面給出了最小的例子。
最小的例子使錯誤消息清晰,似乎MSVC lambda試圖訪問this->__this->a
。 這種訪問序列表明MSVC不捕獲的地址a
(或到參考a
),而是抓住了地址*this
並獲取訪問a
使用這個對象。 由於當弱引用計數變為零時, *this
對象被完全解除分配,因此我有內存訪問錯誤。
顯然,MSVC方法與g ++和clang的方法完全不同。 那么,我的問題是哪個編譯器是正確的?
PS MSVC案例的簡單修復:
#include <functional>
#include <iostream>
#include <list>
#include <memory>
struct foo;
std::list<std::weak_ptr<foo>> wptrs;
std::function<void()> global_func;
struct foo {
int &a;
foo(int &a) : a{ a } { }
~foo() {
global_func = [a = &a] { // capture a ptr instead
wptrs.remove_if([](auto &x) { return x.expired(); });
std::cout << "a= " << *a << std::endl;
};
}
};
int main() {
int a = 5;
auto ptr = std::make_shared<foo>(a);
wptrs.emplace_back(ptr);
ptr = nullptr; // object is destroyed here
global_func();
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.