
Ion GaztaƱaga <igaztanaga@gmail.com> writes:
The optional may be or not constructed, and you have to check that before using optional. I'm trying to avoid dynamic allocation so scoped_ptr is not a good enough solution in my opinion.
The scoped pointer or optional would be employed by the *user* of shmem who wants to achieve that difference in lifetime.
Yes. But I wanted to avoid Shmem users to be forced to use dynamic allocation or optional if the want two-phase initialization.
They're never forced; they can code their own optional. But why are you worried about requiring a user to do that?
Re-reading the proposed C++ N1883 paper Kevlin Henney wrote about threader-joiner architecture similar to smart pointer/new combination:
class threader { public: template<typename nullary_function> joiner operator()(nullary_function threadable); ... };
template<typename threadable> joiner<return_type<threadable>::type> thread(threadable function) { return threader()(function); }
int main () { //Class approach threader run; joiner wait = run(first_task); //or function approach jointer wait2 = thread(second_task); }
Couldn't be an alternative something similar with Shmem primitives:
shared_memory_handle shm = shared_memory(/*open, open/create overloads*/);
shm would be like the proposed joiner (CopyConstructible, Assignable, and DefaultConstructible and Shareable (via an internal shared_ptr, for example) so that I could have a shared_memory_handle member in a class that can be initialized when I want. Much like a shared_ptr member that can be default constructed but only initialized though an external "new T" operation.
I see that since shared_memory_handle has default constructor it can be also a two-phase initialization class (much like shared_ptr) but do you think this architecture is acceptable or you think it has the same problems as the previous one?
Seems like the the same problems to me, unless you provide a different type that offers the guarantee that it's either constructed or it doesn't exist. But then I consider the 2-phase interface to be premature generalization. Getting an interface where a zombie is possible should be the explicit choice. Getting an interface where no zombies are possible should be the default.
I'm trying to offer some alternatives I've seen in proposed WG21 papers (but I'm ready to offer a RAII only interface, as I've said).
IMO unless there's an especially good reason not to (and I haven't seen one here) it's important to offer an RAII-only interface.
Then you clearly don't understand me at all. I'm arguing that interfaces that easily lead to zombie states make components harder to use and code harder to think about. Just providing a *way* to avoid the zombie state does not help me know that I can operate on such an object that I'm passed by reference without first making sure it's not a zombie.
Well, someone can pass you shared_ptr that is empty and we don't forbid an empty shared_ptr.
Yes, that's part of the pointer idiom, so it makes sense there. A shmem is not a pointer. For that purpose can use shared_ptr<shmem> or intrusive_ptr<shmem> or optional<shmem> or...
I think that functions can establish preconditions to say what kind of parameters they expect.
Adding the precondition "it must be a non-zombie shmem object" to most functions that operate on shmems is not an attractive idea. Every time you strengthen preconditions it makes an interface harder to understand and work with effectively. Your library should take responsibility for that, rather than pushing responsibility off on client coders.
I think that apart from this C++ aspect of your knowledge, there is plenty of your C++ knowledge that you can use in other aspects of the library. And I'm really interested in them. Specially, if they are related to correct uses or better idioms like the previous one. And I want to support those idioms. I just want to provide some alternatives apart from your advices.
I think I've used up most of my available energy on this one. :(
Ok. But don't say you were not invited to the party ;-) Now, seriously, I'm ready to offer a RAII only approach if the above described alternative is considered also a bad design. I would only need a class/library that you think it implements well this RAII approach (what kind of exceptions it throws, and so on) to have some good model.
Throw the same ones you would throw from a failed 2nd phase initialization. And so on? I don't know what you have in mind.
I do understand your concerns and I think that Shmem has much more to offer than this initialization problem.
Great; I hope we can get it into Boost. -- Dave Abrahams Boost Consulting www.boost-consulting.com