Pimpl copying

Peter K├╝mmel syntheticpp at gmx.net
Sun Jul 16 20:11:59 BST 2006


Rolf Magnus wrote:
>>>  No. It's just syntactic sugar functionally completely equivalent to the
>>> case below with just normal ctor. If any compiler uses copy ctor here
>>> it's broken.
>> Stroustrup's book says that
>>    KTempDir dir = KTempDir("test");
>> and
>>    KTempDir dir("test");
>> are equivalent. I.e. the first one should not use ctor and then copy.
> 
> I can't believe that. The C++ standard clearly says something else.
> 
>> I had a similar discussion with Mark a while ago (we were discussion which
>> one was more efficient. Turned out they should be the same)
> 
> Well, eliding the copy constructor is an allowed optimization, but not 
> required. Most compilers nowadays do it, AFAIK. However, a copy constructor 
> still _must_ be available, even if the call is optimized away. That's because 
> C++ requires that the correctness of code doesn't depend on optimization 
> behavior. Consider this:
> 
> class Test
> {
> public:
>     Test(int x) { }
> private:
>     Test(const Test&);
> };
> 
> int main()
> {
>     Test t(3);             // will compile
>     Test t2 = Test(3); // won't compile, even if copy constructor is not used
> }
> 
> Any compiler that accepts the above code is broken.

This is not the problem, the problem is the wrong behavior
of the compiler generated copy ctor:

struct Private {
    int i;
};

class Test
{
public:
    Test() : d(new Private) {}
    Test(const Test& rhs) : d(new Private)
        {d = rhs.d;}       // generated by the compiler
        //{d->i=rhs.d->i;} // correct version
    ~Test() {delete d;}
    Private* d;
};

int main()
{
    // ctor only
    Test t1;
    t1.d->i;

    // ctor + copy ctor
    Test* tmp = new Test;
    Test t2 = *tmp;
    delete tmp;
    t2.d->i; // -> seg fault with the compiler generated ctor
}






More information about the kde-core-devel mailing list