[Development] What's the status of a moved-from object?

Edward Welbourne edward.welbourne at qt.io
Mon May 27 10:46:20 CEST 2019


сб, 25 мая 2019 г., 12:30 Mutz, Marc via Development
>>>> Repeat after me: default ctors do _not_ establish a valid value.

As an aged C programmer I can respect that ;^>

On 2019-05-25 17:24, Konstantin Ritt wrote:
>>> Perhaps you mean "trivial type's default ctors do _not_ establish a
>>> valid value"?

сб, 25 мая 2019 г., 20:42 Mutz, Marc via Development <development at qt-project.org<mailto:development at qt-project.org>>:
>> No, I actually meant default ctor. What should the default value be?
>> _Obviously_ zero-initialisation. But oh, no, QSize is different. So
>> maybe it's not _quite_ so obvious what the default value is. Why is
>> pen's default value a black solid line instead of NoPen? Why is
>> QBrush's default ctor not solid black, but NoBrush? See? It's just
>> nonsense to try to pick a default value, so this is to say: Don't
>> try.
>>
>> There's exactly one exception: containers. _Clearly_ no-one would
>> _ever_ expect a container to start out anything but empty.

Indeed.

Konstantin Ritt (26 May 2019 10:51) replied:
> Sure we should force a no-op default ctor where possible, and provide
> some helper code that returns a valid default/specialized value of
> that type where {0} isn't enough or non-intuitive
> (i.e. QQuaternion::identity(), QRect::empty(), QSize::invalid()).

(I can't help but wonder whether QRect::empty() should take a point at
which to place its empty rectangle.  An animated rectangle that shrinks
and expands repeatedly [0] shouldn't forget its location at the moment
when it is transiently empty, so empty rectangles at distinct locations
are distinct.  But I'm unfamiliar with QRect, so maybe not.)

[0] example (in SVG), remembering position and orientation while empty:
    http://www.chaos.org.uk/~eddy/img/geom/transpyth.svg

> There could [be] more exceptions when we're talking about non-trivial
> types, at least some of them could be resolved by providing
> convenience/helper initializers.

Many types need an invalid value (this is the current default for
QDate, QTime, QDateTime and QTimeZone).  But not all.

For arithmetic types, up to and including QQuaternion and matrices,
you'll need a zero-value; many (including square matrices) shall also
need a unit value.  While zero is a natural default, being explicit is
good; and standard integral/floating types don't default to it.

Various others are (at present) constructed with default values.  In the
case of QLocale, that can be controlled by calling a static method,
QLocale::setDefault(), and we'd need to add (as someone tried to do a
little while ago) a QLocale::defaultLocale() or QLocale::getDefault() to
get that (note that we can't use the name QLocale::default() as it's a
reserved word) if we stopped making the default constructor produce it.
Note that QLocale's default isn't the same thing as QLocale::system(),
although it starts out so, until setDefault() is called.

We're not particularly consistent about what default construction
produces; sometimes undefined, sometimes defined but invalid, sometimes
a zero, sometimes a "reasonable" default.  Which, as Marc tripped over,
is a source of confusion for authors of client code.  Having static
methods to return invalid, zero, unit, default values could be made a
consistent pattern, with consistent naming, to reduce confusion.

We can, of course, do that without changing what the default-constructed
objects are, but changing that also to a consistent pattern - the same
as the moved-from state - would make matters clearer (for any choice of
what moved-from state to consistently use).  But it'd be SiC.

	Eddy.


More information about the Development mailing list