[Development] Out of line move constructors
Volker Hilsheimer
volker.hilsheimer at qt.io
Mon Sep 14 22:39:09 CEST 2020
On 14 Sep 2020, at 20:11, Thiago Macieira <thiago.macieira at intel.com> wrote:
>
> On Monday, 14 September 2020 03:37:00 PDT Giuseppe D'Angelo via Development
> wrote:
>> Hi,
>>
>> Many pimpled types in Qt lack a move constructor.
>>
>> History: back in the day, when C++11 wasn't a requirement and binary
>> compatibility between C++98/C++11 was to be kept, we had to implement
>> C++11-only code (such as move operations) inline. This however isn't
>> possible for move constructors if the type is implemented using pimpl
>> (with or without refcounting).
>
> The problem is not a pimpl d-pointer, it's only when said pointer is held by a
> QScopedPointer or similar. The reason for that is the code generation for the
> move constructor must handle the case where an exception is thrown, so it must
> generate a call to the destructor of the smart pointer pointer. Since the
> payload type is only forward declared, the compilation fails.
>
> This has nothing to do with whether an exception *can* be thrown in that
> context or not or whether the compiler will generate a call to the destructor
> anywhere. The compiler simply has to pretend that it could.
>
> See https://gcc.godbolt.org/z/KsjWq7.
>
>> Coming 5.9, C++11 became a requirement. Still we didn't add move
>> constructors for pimpled types; the rationale was that we wanted move
>> operations to be inline. For refcounted types, the idea was to achieve
>> that (I think) by using something like QIntrusiveSharedPointer instead
>> of Q(E)SDP.
>>
>> Anyhow: is this still the policy, or do we want to start adding out of
>> line move constructors?
>
> There's a workaround for the problem above, which is to declare the
> QScopedPointer's destructor as a forward-declaration. This allows compilation
> to proceed and/or even make the destructor inline.
>
> See https://gcc.godbolt.org/z/vGP6oW (difference is line 46).
Thanks for raising this Giuseppe, and for the clarification and workaround, Thiago.
I’ve tried to make this work for
https://codereview.qt-project.org/c/qt/qtbase/+/313610
but now I get ~QExplicitlySharedDataPointer<QPlatformPixmap> as an unresolved external, presumably because the unspecialized ~QExplicitlySharedDataPointer is inline.
Volker
More information about the Development
mailing list