Topic: movable" class property (Was: Aggregated exceptions)


Author: denis bider <isocppgroup@denisbider.com>
Date: Thu, 23 Jul 2015 17:08:24 -0700 (PDT)
Raw View
------=_Part_54_105296015.1437696504888
Content-Type: multipart/alternative;
 boundary="----=_Part_55_869761685.1437696504888"

------=_Part_55_869761685.1437696504888
Content-Type: text/plain; charset=UTF-8

Indeed. That's pretty much what I had before today, when I refactored
things.

It seems to me this is a shortcoming we should fix, no?

99% of classes can be moved using memcpy, but we cannot take advantage of
it.

The language introduced noexcept to deal with a similar property for
methods. How about introducing a class-level property to indicate
memcpy-ability for classes?

We could call the property "movable", and the keyword could appear
contextually after class name:

class A movable {};
class B movable : public A {};

If we did it this way, the compiler could help verify this property by
checking that the class does not aggregate, or inherit from, types that are
in fact NOT movable. For example, the following should fail:

class A { void f(); };  // User defined method; cannot assume class is
movable
class B movable : public A {};   // ERROR - derived can't be movable if
base isn't

But the following would be fine:

struct A {};  // No user defined code; struct is implicitly movable
class B movable : public A {};   // OK

This would be better than macros or typedefs because:
- avoids macro namespace issues
- uses compiler to ensure correctness of "movable" declaration
- provides a mechanism whereby standard containers can use this

Thoughts?


On Thursday, July 23, 2015 at 4:42:25 PM UTC-6, Thiago Macieira wrote:

> On Thursday 23 July 2015 14:18:17 denis bider wrote:
> > We spent 20 years deep copying objects when we want to move them.
> >
> > Are we going to spend another 20 years before we're smart enough to
> expose
> > an "is trivially movable" trait, and then just perform memcpy?
>
> The problem is that this trait is not something the compiler can know for
> certain.
>
> Trivially copyable and movable objects can be memcpy-moved, but there are
> other classes that have complex copy/move constructors and are still
> movable
> by memcpy. That is, a compiler trait would have no false positives, but
> would
> have a lot of false negatives. Example: almost every container and
> value-type
> class.
>
> So this isn't something that needs a change in the core language. It's a
> library change.
>
> We have it in Qt, but it's ugly (macro, namespace problems):
>
> Q_DECLARE_TYPEINFO(MyClass, Q_MOVABLE_TYPE)
>
> This specialises QTypeInfo<MyClass> and sets isMovable = true. This way,
> Qt
> container classes know this type can be memcpy'ed.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>    Software Architect - Intel Open Source Technology Center
>       PGP/GPG: 0x6EF45358; fingerprint:
>       E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358
>
>

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_55_869761685.1437696504888
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Indeed. That&#39;s pretty much what I had before toda=
y, when I refactored things.<br></div><div><br></div><div>It seems to me th=
is is a shortcoming we should fix, no?</div><div><br></div><div>99% of clas=
ses can be moved using memcpy, but we cannot take advantage of it.</div><di=
v><br></div><div>The language introduced noexcept to deal with a similar pr=
operty for methods.=C2=A0How about introducing a class-level property to in=
dicate memcpy-ability for classes?</div><div><br></div><div>We could call t=
he property &quot;movable&quot;, and the keyword could appear contextually =
after class name:</div><div><br></div><div>class A movable {};</div><div>cl=
ass B movable : public A {};</div><div><br></div><div>If we did it this way=
, the compiler could help verify this property by checking that the class d=
oes not aggregate, or inherit from, types that are in fact NOT movable. For=
 example, the following should fail:</div><div><br></div><div><div>class A =
{ void f(); };=C2=A0 // User defined method; cannot assume class is movable=
</div><div>class B movable : public A {};=C2=A0=C2=A0 // ERROR - derived ca=
n&#39;t be movable if base isn&#39;t</div><div><br></div><div>But the follo=
wing would be fine:</div><div><br></div><div><div>struct A {};=C2=A0 // No =
user defined code; struct is implicitly movable</div><div>class B movable :=
 public A {};=C2=A0=C2=A0 // OK</div><div><br></div></div><div>This would b=
e better than macros or typedefs=C2=A0because:</div><div>- avoids macro nam=
espace issues</div><div>- uses compiler to ensure correctness of &quot;mova=
ble&quot; declaration</div><div>- provides a mechanism whereby standard con=
tainers can use this</div></div><div><br></div><div>Thoughts?</div><div><br=
></div><div><br>On Thursday, July 23, 2015 at 4:42:25 PM UTC-6, Thiago Maci=
eira wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px=
 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); borde=
r-left-width: 1px; border-left-style: solid;">On Thursday 23 July 2015 14:1=
8:17 denis bider wrote:
<br>&gt; We spent 20 years deep copying objects when we want to move them.
<br>&gt;=20
<br>&gt; Are we going to spend another 20 years before we&#39;re smart enou=
gh to expose
<br>&gt; an &quot;is trivially movable&quot; trait, and then just perform m=
emcpy?
<br>
<br>The problem is that this trait is not something the compiler can know f=
or=20
<br>certain.
<br>
<br>Trivially copyable and movable objects can be memcpy-moved, but there a=
re=20
<br>other classes that have complex copy/move constructors and are still mo=
vable=20
<br>by memcpy. That is, a compiler trait would have no false positives, but=
 would=20
<br>have a lot of false negatives. Example: almost every container and valu=
e-type=20
<br>class.
<br>
<br>So this isn&#39;t something that needs a change in the core language. I=
t&#39;s a=20
<br>library change.
<br>
<br>We have it in Qt, but it&#39;s ugly (macro, namespace problems):
<br>
<br>Q_DECLARE_TYPEINFO(MyClass, Q_MOVABLE_TYPE)
<br>
<br>This specialises QTypeInfo&lt;MyClass&gt; and sets isMovable =3D true. =
This way, Qt=20
<br>container classes know this type can be memcpy&#39;ed.
<br>
<br>--=20
<br>Thiago Macieira - thiago (AT) <a onmousedown=3D"this.href=3D&#39;http:/=
/www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;" onclick=3D"this.=
href=3D&#39;http://www.google.com/url?q\75http%3A%2F%2Fmacieira.info\46sa\7=
5D\46sntz\0751\46usg\75AFQjCNEswDUBNCNanbu7euhqLn_62FW8ag&#39;;return true;=
" href=3D"http://macieira.info" target=3D"_blank" rel=3D"nofollow">macieira=
..info</a> - thiago (AT) <a onmousedown=3D"this.href=3D&#39;http://www.googl=
e.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\75AFQjCNHGRJd=
o5_JYG1DowztwAHAKs80XSA&#39;;return true;" onclick=3D"this.href=3D&#39;http=
://www.google.com/url?q\75http%3A%2F%2Fkde.org\46sa\75D\46sntz\0751\46usg\7=
5AFQjCNHGRJdo5_JYG1DowztwAHAKs80XSA&#39;;return true;" href=3D"http://kde.o=
rg" target=3D"_blank" rel=3D"nofollow">kde.org</a>
<br>=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center
<br>=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:
<br>=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C =C2=A0966C 33F5 F005 6EF4=
 5358
<br>
<br></blockquote></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_55_869761685.1437696504888--
------=_Part_54_105296015.1437696504888--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 23 Jul 2015 19:28:50 -0700
Raw View
On Thursday 23 July 2015 17:08:24 denis bider wrote:
> Indeed. That's pretty much what I had before today, when I refactored
> things.
>
> It seems to me this is a shortcoming we should fix, no?
>
> 99% of classes can be moved using memcpy, but we cannot take advantage of
> it.

I wouldn't say 99% of classes. First of all, at least have of the classes are
not copyable or movable at all. But I will agree that a very big portion --
probably the majority -- of copyable classes can be moved with memcpy.

In fact, we have more traits to specialise:
 * can be initialised by memset
 * can be cloned by memcpy
 * can be moved by memcpy

clone = both source and destination continue to be used
moved = only the destination is used; the source is no longer used and no
destructor is called

> The language introduced noexcept to deal with a similar property for
> methods. How about introducing a class-level property to indicate
> memcpy-ability for classes?

The closest thing we have to that are attributes. We're only missing a way to
query the attributes. Either way, we'll need a way to query this extension.

I don't think this violates "attributes don't affect compilation": the compiler
couldn't care less and will not use the attribute for moving anyway. Container
classes, however, can do that. It's no different than using an additional
traits class (with or without a macro, like Q_DECLARE_TYPEINFO) or an extra
code generator.

> We could call the property "movable", and the keyword could appear
> contextually after class name:
>
> class A movable {};
> class B movable : public A {};

If we get a way to query attributes, then we won't need a keyword.

class A [[std::movable]] {};
class B [[std::movable]] : public A {};

> If we did it this way, the compiler could help verify this property by
> checking that the class does not aggregate, or inherit from, types that are
> in fact NOT movable. For example, the following should fail:
>
> class A { void f(); };  // User defined method; cannot assume class is
> movable
> class B movable : public A {};   // ERROR - derived can't be movable if
> base isn't

Not sure that deriving from a non-movable implies non-movable. There may be
some conditions that specialisation-through-derivation does mean it's movable.

In any case, even if this exists, the compiler can produce diagnostics due to
attributes. It just can't be required to produce them.


--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.