Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

intrusive_weak_ptr #81

Open
strimo378 opened this issue Aug 3, 2020 · 3 comments
Open

intrusive_weak_ptr #81

strimo378 opened this issue Aug 3, 2020 · 3 comments

Comments

@strimo378
Copy link

Hi everybody,

I have implemented a weak version of intrusive_ptr. The basic idea is that the destructor call and memory deallocation is performed independently. Destructor is called if use_count = 0 and deallocation in case of weak_count = 0.

Please find attached the first implementation of instrucive_weak_ptr and the corresponding intrusive_weak_ref_counter. The current implementation is without any modifications of the original smart_ptr source code and does not support all compilers/architectures.

I have tested the implementation on gcc 8.3 and VS 2019 with an internal compiler project with heavy usage of smart pointers within the AST.

Please let me know if the intrusive_weak_ptr implementation could be integration into the boost library. In that case, I would love to finalize it for an official integration.

Kind regards,

Timo Stripf
intrusive_weak_ptr.zip

@strimo378 strimo378 changed the title instruction_weak_ptr intrusive_weak_ptr Aug 3, 2020
@pdimov
Copy link
Member

pdimov commented Oct 24, 2020

Interesting idea, but ~Derived also destroys intrusive_weak_ref_counter, and accessing m_weak_counter after that is undefined behavior.

This can be hacked around in single-threaded by constructing an intrusive_weak_ref_counter at the same place, with the same counter values, but it doesn't work if another thread increments m_weak_counter at the same time.

One way to do this by the book would be to not destroy the object and instead call a virtual function in the derived class, say, intrusive_ptr_destroy, that would be responsible for releasing resources.

@strimo378
Copy link
Author

I see your point that it is problematic to use objects after their destructor has been called. I would specify it as an requirement that the destructor call is not changing/resetting the weak counter value. Fundamental types have no default destructor that could change their value.

Can you tell me the C++ standard paragraph that defines accessing m_weak_counter as undefined behaviour? I found several possible paragraphs but I am unsure which really defines it.

I think the hack would also work for multi-threaded code if a constructor is called that is doing nothing. Reusing storage is afaik allowed. A constructor and destructor of intrusive_weak_ref_counter that is doing nothing would pratically work but in theory if another thread is accessing the pointer value between both calls would be undefined :)

I like the idea of intrusive_ptr_destroy and maybe a intrusive_ptr_delete function.

@hadrielk
Copy link

Can you tell me the C++ standard paragraph that defines accessing m_weak_counter as undefined behaviour?

Section 15.7 of C++17 spec:

For an object with a non-trivial destructor, referring to any non-static member or base class of the object after the destructor finishes execution results in undefined behavior.

Since the intrusive weak-ref-count would be in the base class of some derived class T, it could not be accessed after the destruction of T without being undefined behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants