[Development] Setters: Passing by value or const reference?

Marc Mutz marc.mutz at kdab.com
Tue May 8 15:42:41 CEST 2012


Hi Olivier,

Please excuse the delay in answering.

On Wednesday April 25 2012, Olivier Goffart wrote:
> On Wednesday 25 April 2012 15:07:24 Marc Mutz wrote:
[...]
> > > We could implement a move setter (Foo::setText(QString&&)).  But that
> > > would
> > > mean  duplication, and it could not be inline (access to d_ptr) so
> > > binary incompatibility between Qt compiled with or without C++11.
> >
> > The rvalue overloads could only be used by a C++11 compiler, and it would
> > be natural for a C++11 app to require a C++11-compiled Qt.
>
> Not really...
> On linux, if the dirstribution provides a qt compiled without C++11, i
> still want to be able to use C++11 it on my project.
> C++11 is still (unfortunatelly) not the default to build Qt on linux.

Good point. That might be a problem for KDE.

OTOH, if you as an ISV depend on the distribution's Qt, you're probably 
targeting LSB anyway, and then it's in our hands (or is it?) to say that 
QSslKey(QSslKey &&) is a required symbol in the next version of LSB's 
libQtNetwork.so

So, what's the solution? For move ctors, we can go back to naked pointers to 
keep them inline, but not for setters and other constructors (E.g. 
QDir(QString &&)).

> > There's no such thing as binary compatibility between compilations using
> > different flags anyway.
>
> Yes there is!
> On linux, Qt debug is binary compatible with Qt release

On Windows, they're not :)

> Most of the flags like -fno-exceptions  ... are still binary compatible.

What happens if an exception travels through C++ code compiled 
with -fno-exceptions? Will it pass through? Will it call all dtors? Or will 
it ruin the stack? (Not a rhetorical question: I really don't know myself).

I was thinking about -falign-double, -mms-bitfields, -stdlib=libcxx etc, which 
are all highly binary-incompatible changes (well, unless you explicitly pad 
all doubles in all exported objects, avoid bitfields and std:: types in the 
API).

> > Indeed, most move constructors (excepting the few you implemented)
> > cannot be implemented inline (because they require the definition of
> > ~FooPrivate),
>
> It is possible if you don't use smart pointer.
> This is really unfortunate.  Why is it the case? Is there a way to avoid
> it?

http://stackoverflow.com/questions/9417477/where-does-the-destructor-hide-in-this-code

I don't think there is. I'm tending towards using naked pointers instead. 
Swapping makes much of the pain they were supposed to help with simply go 
away.

[...]
> > > void Foo::setText(QString text) {	d_ptr->text = qMove(text); }
> >
> > You should use d_ptr->text.swap(text) instead, that's just as fast (maybe
> > even faster) and requires no C++11 :)
> >
> > Talking of swap: I have a half-finished patch that makes Q_DECLARE_SHARED
> > implement the two op='s with (copy)-swap (and adds swap() to classes that
> > would benefit from it, but don't have it yet).
> >
> > Foo &Foo::operator=(const Foo &other)
> > { if ( this != &other ) { Foo copy(other); swap(other); } return *this; }
> > Foo &Foo::operator=(Foo &&other)
> > { other.swap(*this); return *this; }
> >
> > I'll try to get it into a reviewable state.
[...]

Parts of it are uploaded now, cf. my mail to the list about them a few minutes 
ago.

Thanks,
Marc


-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions



More information about the Development mailing list