내 동료 중 한 사람은 객체의 소멸자 호출이 시작되자 스레드 (객체 자체의 구성원)에 의해 수행 된 객체 구성원에 대한 모든 액세스가 인 것을 UB라고 주장합니다.부모 소멸자에서 부모 클래스의 다른 멤버에 액세스하는 멤버 스레드를 조인하면 정의되지 않은 동작이 발생합니까?
이것은 스레드가 객체의 다른 구성원 중 하나에 액세스하는 경우 객체의 소멸자 중에 std::thread::join
을 호출하는 것이 UB임을 의미합니다.
"Object Lifetime" 아래의 최신 표준 초안을 간략하게 살펴 보았지만 결론적 인 대답을 찾지 못했습니다.
다음 코드 (on wandbox)은 의 정의되지 않은 동작을 나타냅니다.?이 상호 작용을 명확히하는 표준 부분은 무엇입니까?
struct A
{
atomic<bool> x{true};
thread t;
// Capturing 'this' is part of the issue.
// The idea is that accessing 'this->x' becomes invalid as soon as '~A()' is entered.
// vvvv
A() : t([this]
{
while(x)
{
this_thread::sleep_for(chrono::milliseconds(100));
}
})
{
}
~A()
{
x = false;
t.join();
}
};
int main()
{
A a;
}
아무 의미가 없습니다. 그는 소멸자에서 원시 멤버 포인터를 삭제하는 것이 UB이기도하다는 것을 의미합니까? 메인 스레드에서 발생했거나 경쟁 조건과 잘못된 코드를 의미하는 소멸자를 실행하는 2 개의 스레드를 의미하기 때문입니다. 당신은 그에게 그의 믿음의 근원을 더 잘 물어 봐야합니다 :) – Arunmu
"** [class.cdtor]/1 ** 비 정적 인 소멸자가있는 객체의 경우, 객체의 비 정적 멤버 또는 기본 클래스를 참조하십시오. * 소멸자가 실행을 끝내면 정의되지 않은 동작이 발생합니다. " 강조. 이것은 소멸자가 실행을 끝내기 전에 멤버에 액세스하는 것이 좋다고 암시하는 것으로 보입니다. –
그것에 대해 생각해보십시오. _ 전형적으로 소멸자에서 수행하는 작업은 아직 살아있는 구성원에 따라 다릅니다. 소멸자는 작업 할 수있는 어떤 인자도 가지고 있지 않습니다. 유일한 것은'this'이므로'this->'는 사용 가능한 객체를 더 잘 참조합니다. – MSalters