Date: Thu, 29 Jan 2026 08:37:37 -0800
On Thursday, 29 January 2026 04:30:05 Pacific Standard Time Frederick Virchanza
Gotham via Std-Proposals wrote:
> The above is more complicated, and we see that memcpy is called
> several times in a loop. I tried re-writing it to use pointers instead
> of an integer index:
>
> void CopyB(void *const dstV, S const *src, size_t const count)
> {
> S *dst = (S*)dstV;
> S const *const dst_over = dst + count;
> while ( dst != dst_over ) ::new(dst++) S(*src++);
> }
>
> But it comes out pretty much the same.
>
> So we can see that calling a copy-constructor in a loop isn't
> efficient.
Missing from your statement: "with this implementation". There's nothing
inherently making the calls to trivial copy-constructions less efficient. This
is QoI.
> Let's see if we can trust the compiler to do a better job
Ill-fated test. You can't prove a negative: if the compiler does a better job,
great, it proves it can do a better job. But if fails to do a better job, that
doesn't tell you whether it could have if it had better algorithms in the first
place.
> So we can see here that we've lost all the efficiency because we made
> S polymorphic
True, but again that doesn't tell us whether the compiler could have been more
efficient. All it shows is that it wasn't. Go file bug reports if this is
important to you.
I argue that vectors/arrays of polymorphic types, final or not, are uncommon.
See Jason's email.
> Unless I misunderstand what you mean by type-erasing the copy operation. . .
> ?
You did. Your trivial implementation of std::any and QVariant is too simple.
You're missing the "small object optimisation", which you realised later:
> Oh wait . . . . . just now as I write this, I've checked the Qt
> manual, and it turns out that QVariant doesn't use dynamic allocation,
> i.e. the object is stored internally a sub-object, and so if that
> sub-object is polymorphic, and if you move or relocate the QVariant,
> then you'll have to re-sign the sub-object's vptr's and vbptr's. Same
> goes for 'std::variant'. I'm wondering now Thiago if you meant to
> write 'std::variant' instead of 'std::any' in your above post?
No, I didn't. QVariant is equivalent to std::any, not std::variant. Though
std::variant could indeed also have the same need: being relocatable.
QVariant is itself relocatable. That means it can be memcpyed around. That
means it can only hold types that can be memcpyed around -- for types that
can't, it stores a pointer (which can be) and stores the object elsewhere in
the heap.
> Specifically here's what I think we need to do with copying and moving:
> Point 1) Allow the memcpy'ing of final polymorphic classes and
> also guaranteed complete objects
> Point 2) Decide what to do about Apple Silicon
Opinion on Point 1 is not shared, so it's not "we need to do". Only you
apparently still has a problem with it.
Point 2 I agree needs to be understood properly.
> Strategy 1) Have 'is_trivially_copy_constructible' be false for
> all polymorphics on Apple Silicon
The answer should be the same in all silicon. It should not depend on the
implementation. Right now, we don't need to do anything because no polymorphic
object can be trivially copied. So what you're asking is to *introduce* a
problem we don't currently have, for a need we don't agree we have either.
Gotham via Std-Proposals wrote:
> The above is more complicated, and we see that memcpy is called
> several times in a loop. I tried re-writing it to use pointers instead
> of an integer index:
>
> void CopyB(void *const dstV, S const *src, size_t const count)
> {
> S *dst = (S*)dstV;
> S const *const dst_over = dst + count;
> while ( dst != dst_over ) ::new(dst++) S(*src++);
> }
>
> But it comes out pretty much the same.
>
> So we can see that calling a copy-constructor in a loop isn't
> efficient.
Missing from your statement: "with this implementation". There's nothing
inherently making the calls to trivial copy-constructions less efficient. This
is QoI.
> Let's see if we can trust the compiler to do a better job
Ill-fated test. You can't prove a negative: if the compiler does a better job,
great, it proves it can do a better job. But if fails to do a better job, that
doesn't tell you whether it could have if it had better algorithms in the first
place.
> So we can see here that we've lost all the efficiency because we made
> S polymorphic
True, but again that doesn't tell us whether the compiler could have been more
efficient. All it shows is that it wasn't. Go file bug reports if this is
important to you.
I argue that vectors/arrays of polymorphic types, final or not, are uncommon.
See Jason's email.
> Unless I misunderstand what you mean by type-erasing the copy operation. . .
> ?
You did. Your trivial implementation of std::any and QVariant is too simple.
You're missing the "small object optimisation", which you realised later:
> Oh wait . . . . . just now as I write this, I've checked the Qt
> manual, and it turns out that QVariant doesn't use dynamic allocation,
> i.e. the object is stored internally a sub-object, and so if that
> sub-object is polymorphic, and if you move or relocate the QVariant,
> then you'll have to re-sign the sub-object's vptr's and vbptr's. Same
> goes for 'std::variant'. I'm wondering now Thiago if you meant to
> write 'std::variant' instead of 'std::any' in your above post?
No, I didn't. QVariant is equivalent to std::any, not std::variant. Though
std::variant could indeed also have the same need: being relocatable.
QVariant is itself relocatable. That means it can be memcpyed around. That
means it can only hold types that can be memcpyed around -- for types that
can't, it stores a pointer (which can be) and stores the object elsewhere in
the heap.
> Specifically here's what I think we need to do with copying and moving:
> Point 1) Allow the memcpy'ing of final polymorphic classes and
> also guaranteed complete objects
> Point 2) Decide what to do about Apple Silicon
Opinion on Point 1 is not shared, so it's not "we need to do". Only you
apparently still has a problem with it.
Point 2 I agree needs to be understood properly.
> Strategy 1) Have 'is_trivially_copy_constructible' be false for
> all polymorphics on Apple Silicon
The answer should be the same in all silicon. It should not depend on the
implementation. Right now, we don't need to do anything because no polymorphic
object can be trivially copied. So what you're asking is to *introduce* a
problem we don't currently have, for a need we don't agree we have either.
-- Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org Principal Engineer - Intel Data Center - Platform & Sys. Eng.
Received on 2026-01-29 16:37:46
