Boost logo

Boost :

Subject: Re: [boost] [pimpl] Mini Review
From: Stewart, Robert (Robert.Stewart_at_[hidden])
Date: 2011-06-01 07:12:30


Sean Chittenden wrote:

Don't snip attributions for quoted material, please.

> > I still don't think it is correct behavior for a library
> > implementing the Pimpl Idiom to modify the interface class'
> > (Book's) interface. Consider a raw pointer Pimpl design:
> >
> > class Book
> > {
> > // state
> > };
> >
> > becomes:
> >
> > class Book
> > {
> > struct impl;
> > impl pimpl_;
> > };
> >
> > struct Book::impl
> > {
> > // state
> > };
> >
> > Adding a pimpl did nothing to Book's interface. Why then
> > should Book's interface change when using your library? That
> > seems to be an extension of the idiom into the territory of
> > the Bridge Pattern or something else entirely.
>
> I've been watching this discussion for a while (with vested
> interest), and want to use a few examples to shore up some of
> the discussion (and possibly move it off list so that things
> can proceed in a constructive manner). The concern is not that
> Pimpl is implementing an opaque pointer, it's the miscellaneous
> copy constructors, constructors, equality or whatever other
> misc "extras" that come along from using Pimpl, right?

Not quite. Copy constructors and copy assignment, for example, are appropriate. They allow the library to manage copies of the implementation object. Problems arise, for example, from the addition of null(),operator ->(), and operator *().

reset(), which may be protected rather than public (I don't recall), is not as much of a problem, but my suggestion for that was that since the constructors allocate the implementation object, "resetting" the implementation should likewise not involve allocation. For that, I suggested a construct() member function template set, paralleling the constructors that implement "perfect forwarding." A constructor and a reset() that take a deleter would be appropriate for cases in which allocation is not desired. That design would be symmetrical.

> To recap (using pointer semantics since that's my preferred
> implementation):
>
> > // book.h
> >
> > class Book : public pimpl< Book >::pointer_semantics {
> > // interface
> > };
> >
> > // book_impl.cc
> >
> > template<> struct pimpl< org::example::String
> >::implementation : boost::noncopyable {
> > // impl state
> > }
> >
> > Book::Book() : base() { }
> >
> > // user.cpp
> >
> > Book b;
> > std::cout << "sizeof(Book): " << sizeof(b) << std::endl;
>
> > From an ABI perspective, Book implemented via Pimpl
> > maintains the same size (currently 16 bytes, regardless of
> > Book::implementation), and thereby provides a stable ABI (if
> > someone really was concerned about future-proofing their
> > frontend ABI, they could pad Book in book.h).

That much is fine.

> > I think the concern is coming from:
>
> > Book* b2 = new Book();
> > Book* b1 = b2;
>
> because there possibly isn't a clear understanding of how those
> mechanics would work with Pimpl (yes?). Or is it because it's
> unclear how you'd obtain the desired copy semantics - for
> example - with the proposed Pimpl library?

I have no problem with Pimpl managing the implementation copying.

> > Modifying the interface is the part I was referring to.
>
> How is Book's interface different?
>
> > // Is the Interface different because of the inheritance?
>
> > class Book : public pimpl< Book >::pointer_semantics { };
> > // Or is the interface different because the ABI is
> > // different?
> > class Book {
> > class* impl_;
> > };

It's different because using inheritance and public member functions, pimpl<Book>::whatever has augmented Book's interface.

> Would a Pimpl implementation with preprocessor directives be
> more suitable because of the level of explicitness?

No.

> Also, Pimpl implements an opaque pointer and successfully
> breaks compilation dependencies. Pimpl is not a Bridge
> implementation.

The intent of the Bridge Pattern is to "decouple an abstraction from its implementation." While the Pimpl Idiom is not about an abstraction, by augmenting the interface of Book, the Pimpl Library is crossing the boundary from the Pimpl Idiom into Bridge or something else.

> With as (in?)efficient compilers sucking up gigs of RAM and
> frequently crashing during compilation[1], having a friendly
> mechanism to hide linkage and implementations behind opaque
> pointers is useful beyond externally exposed APIs in libraries.
> The tedium of doing this frequently makes the Pimpl library an
> easy win for many developers (though possibly not all of them
> and not in all situations). As a Pimpl consumer for over a
> year, I'm trying to concretely demonstrate where the possible
> pitfalls could be lurking with this implementation. Thanks in
> advance. -sc

I have no problem with using the Pimpl Idiom. Just this past week I was able to advance some application testing readily because we used it in a couple of classes involved in an application's disorderly shutdown due to misconfiguration. My concern is that the Pimpl Library seems to have pushed past the idiom into something else, which is surprising to me and, clearly, to others. I should also be clear that I'm not against what the Pimpl Library has done, in terms of augmenting the derivate's interface via public inheritance, but that doing so should be in a class template and a library of a different name.

_____
Rob Stewart robert.stewart_at_[hidden]
Software Engineer using std::disclaimer;
Dev Tools & Components
Susquehanna International Group, LLP http://www.sig.com

IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk