On 12 Nov 2020, at 15:37, Giuseppe D'Angelo 
<[email protected]<mailto:[email protected]>> wrote:

Il 12/11/20 15:13, Lars Knoll ha scritto:
Is_trivial() explicitly states that you can memcpy/memmove objects and I really 
want to keep this. With your change, those will by default fall back to the 
complex case, slowing down operations on that list.

The right detection for copies and copy assignments isn't is_trivial, but 
is_trivially_copyiable. At the beginning of the thread, I was indeed confused 
by this; we are conflating multiple independent semantics into the "primitive" 
/ "isComplex" case.

is_trivial implies is_trivially_copyable, see 
https://en.cppreference.com/w/cpp/types/is_trivial.


Should they be split in *independent* semantics? At least 1/2 are different:

I was thinking about that as well, but that’s more refactoring that I’m willing 
to do just now before 6.0. Maybe for 6.1?

1) Can be value constructed with memset(0)
 * Primitive: yes by definition
 * Trivial(ly constructible): not in general, see the PDM example
 * Relocatable: not in general

2) Can be copy/move constructed/assigned with memcpy
 * Primitive: yes by definition
 * Trivial(ly copy constructible): yes
 * Relocatable: not in general

3) Can be relocated with memcpy
 * Primitive: yes by definition
 * Trivial(ly copy constructible, destructible): yes
 * Relocatable: yes by definition

4) Can be destroyed by just freeing memory
 * Primitive: yes by definition
 * Trivial(ly destructible): yes
 * Relocatable: not in general

So except for the memset(0) for default construction, Primitive and Trivial 
have the same conditions in your list here. My proposal would be to drop the 
memset(0) optimisation and with that unify those two groups.

(Note: I'm completely ignoring the lifetime issues at just blessing a block of 
memory and saying "there are N objects here". Thiago is right, we shouldn't 
ignore that. But I'm not sure how, except by biting the bullet and calling 
constructors/destructors, then relying on the compiler to do the right thing.)

Those lifetime issues need to be tackled differently. One option could be to 
abandon all our optimizations in a checked build, and only enable them in 
release mode.

--

Language Lawyer Hat: is_trivial is the wrong type trait when it comes to detect 
trivial copiability anyhow, example:

 struct S { int i; S operator=(const S &)=delete; };

is trivial and not copy assignable. Isn't C++ a fun language to work with... :P

Sigh… is_trival implies is_trivially_copyable. That one implies 
https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable, which implies 
that all “eligible” copy/move constructor and assignment operators are trivial. 
But they don’t disallow deleting them (as that makes the operator not eligible).

So what are the correct traits then? Sounds like “is_trivially_copyable and no 
deleted copy/move operators” is about what we need :/

Cheers,
Lars


_______________________________________________
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to