-
Notifications
You must be signed in to change notification settings - Fork 76
FEAT: Support for polymorphism in persistent_ptr<> #374
Comments
Hi, lack of polymorphic types support is not a missing implementation in libpmemobj++, but rather missing standard specification for vtable implementation and position in object's layout. So rather than a question "when" we are facing problem "if and how". For workarounds: we are struggling similar problems in concurrent hashmap implementation, @igchor and @vinser52 may say something more. About C++ standard limitations in general - you can check out draft version of our blogpost: https://szyrom.github.io/2019/06/26/cpp-limitations.html |
Just wondering if you could share more on how you solved the isues in concurrent hashmap and if they might be relevant for this topic? Also adding xref to #363 (comment) re another workaround for polymorphism using v<> |
In concurrent_hash_map we did not really needed polymorphism so I guess guess there's not much to share on that. One thing I can say (which we basically discovered during hash_map testing) is about inheritance in general. If you have a base class with some members and create a derived class with some additional members then the derived one will not pass std::is_standard_layout<> (at least in C++11, I'm not sure about the later standards). If you care about that (and we do) then even if polymorphism would work use cases would be quite limited. |
Regarding standard layout, it seems the main driver is:
In our case though, it seems we are using this to try to maintain a consistent pool layout. However, it does put some restrictions on us. Is the implied requirement that you want to maintain a pool layout that's compatible between platforms, compilers and compilations? We've seen that might already be an issue with #776. Can we get different benefits if we're willing to stick with a given platform and compiler? Notwithstanding documentation, would it be ok to use inheritance if the base class contained no member data, only functions? This would allow enforcement of implementation of required virtual functions for example. And since there's no base class member data, the data segment should be concrete. We do have an issue still with vtable, but will come to that... I used nucleus to try this out. Here is the lab branch. Specific parts:
This all compiles and runs seemingly without issue.
Some observations & questions:
And some more general questions:
Out of interest, I tried out some of the type traits on these objects in code here: Output:
At first I was concerned MyApp didn’t meet the requirements, however it seems Lastly, there are more options I'm still looking into such as static inheritance through templates and separating code from storage like I discuss in #363 (ref) |
I don't think there is any compiler which would actually reorder the members (this is what standard layout basically forbids). This is just one step closer to a properly defined behavior. I know there are still things like object lifetime, trivial copying etc. which result in UB but this is just some kind of compromise. I don't know what specifically can be changed but the problem is that we have no way of rebuilding it reliably. If you would like to do that you would probably have save vtable on pmem (in some fixed format?) and then modify _vptr pointer on each application run (and restoration of _vptr could be compiler specific). There is no problem with derived classes itself (without virtual methods), you can cast using just static_cast. The only persistent region is the heap (that's what pmemobj exposes to you). Changing implementation is OK. |
The very first prototype implementation of C++ bindings actually had polymorphism support: But we've decided that it was too fragile and non-portable and so this code was ultimately removed. |
Closing this issue/question, but one interesting observation is that static polymorphism like CRTP https://www.fluentcpp.com/2017/05/12/curiously-recurring-template-pattern/ does seem to work ok :-) |
Per https://software.intel.com/en-us/articles/an-introduction-to-persistent-memory-pointers-in-c-plus-plus and other references in the documentation:
Is this likely to be addressed in the nearish future, and/or any thoughts on short term workarounds? :-)
The text was updated successfully, but these errors were encountered: