[Development] RFC: Proposal for a semi-radical change in Qt APIs taking strings

Thiago Macieira thiago.macieira at intel.com
Sat Oct 17 01:18:47 CEST 2015


On Friday 16 October 2015 22:08:59 Branislav Katreniak wrote:
> Thiago described Qt6 QString as { QArrayData *d; ushort* b; qsize size }.
> That is pretty close to QStringView, just extra *d makes it slightly bigger.
> 
> This is how I understand this class:
> QString will have (typical) case when b points into d. QString own one
> reference in d in this case.
> QString will have special case when b points to text section and d does not
> own anything.
> QString will have special case for SSO.
> 
> Can QString have special case for not owned, non persistent b pointer
> (non-owning / view mode)?

How is that different from your second case? If it doesn't own, it doesn't need 
a d pointer.

> Non-owning QString can be created with special static QString method. It
> stays non-owning only while being passed through const &. Code that cares
> about keeping QString in view mode, must stick to const QString & all the
> time. Copy assignment on non-owning QString results in owning QString - it
> triggers deep copy into newly created shared data.

Ok, I understand the difference, but why do you want this behaviour? BTW, this 
is the unsharable strings that we're getting rid of.

This would make sense to view a string of ephemeral data. But if the data is 
ephemeral, why can't we use the refcounter? In other words, if someone owns 
this data, why isn't that QString?

> It solves the queued connection problem that existed with QStringView
> class. I suppose that queued connection internally performs QString copy.

True, but I think that having QString share refcount of substrings solves the 
problem that QStringView was proposed for in the first place.

> I have no idea about performance implications for code paths that do not
> care about this use case. But having just one string class would be very
> convenient.

That is the problem. That's the reason we're trying to get rid of unsharable 
containers: performance impact on the code paths that don't need it, which are 
the majority of cases.

There are two possibilities for the unsharable flag:

1) it's inside the d pointer, which means the d pointer must be non-null. That 
means even the non-owning QString needs to allocate memory for the d pointer 
block.

2) it's outside the d pointer, which means that
 a) it doesn't need to allocate memory
 b) we need to extend QString to be:
  { QArrayData *d; ushort *b; qsize size; int flags; }
  (24 bytes if qsize is 32-bit on 64-bit platforms; 32 if it is 64-bit; always 
   16 bytes on 32-bit platforms)

Either way, the existence of the flag means that every QString copy-assignment 
needs to check this flag, instead of simply incrementing the refcount if d is 
not null and being done with it. That means code bloat for the deep copy 
showing up everywhere.

I really don't want the unsharable flag.
-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list