[Development] Wishes for C++ standard or compilers

Thiago Macieira thiago.macieira at intel.com
Sat Mar 18 22:20:49 CET 2017


Ville asked what would be nice to have, so I put together a list:

== SD-6 feature macros ==
We made a decision not to add Q_COMPILER_xxx macros in Qt past C++11, and only 
depend on the ones from the standard. But there are several problems there:

* some compilers don't have them at all (MSVC). Our current answer is "if you 
don't #define them, they don't exist" and therefore for us, MSVC has zero C++14 
features.

* some macros exist but are insufficient, as there are often bugs in 
implementations. You can see in qcompilerdetection.h where we've noted a 
feature being available in a compiler version further than where the compiler 
vendor said it is available (like GCC initializer_list, MSVC constexpr). If we 
use only what the compiler vendor claims, we may run into bugs.

* some features are only marked by __has_include, which sometimes isn't 
sufficient as the header is present by fails to compile.

== QString, QStringView, QByteArray ==

I've been thinking for the past 5 years what QString would look like then and 
how to avoid emitting atomic detaching code all over the place while not 
abandoning implicit sharing. I have some unfinished ideas I can share at a 
later time (glimpse given in the other thread).

There's a question of whether QString should change encoding. I feel that it's 
simply not possible to change this, ever. 

In terms of what we'd need from the standard for UTF-16? Not much. Quite 
frankly, if the standard library sucks when it comes to Unicode, it's to Qt's 
benefit. As a former colleague of ours said some 10 years ago when we found 
QString symbols inside an application from a major OS vendor, "world 
domination starts with QString".

== Containers ==

And then there's what to do with the containers. Here's where Marc's opinion 
and mine differ considerably. Aside from the need to maintain source 
compatibility, I feel like we should keep our containers and keep implicit 
sharing (same solution as for QString). We know COW can be a pessimisation for 
performance-sentive code, but the question is whether it is so for regular 
developers who don't know how to write performance-sensitive code. If 
developers will make mistakes, can we reduce the impact?

== Misc ==

Off the top of my head, here are some things. Not all of these will be 
standards things, but might be compiler-specific.

* better support for the Qt way of atomic implicitly-sharing. Specifically, 
that when the refcount is 1, the refcount stays at 1 unless the function in 
question increments it or calls a non-const function. 
Maybe this is about pre- and post-conditions? See
  http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0542r0.html

* really const: The following reloads the s.i:
        struct S 
        { 
          int i; 
          void f() const;
        };

        void f(const S &);
        int f()
        {
                S s = { 0 };
                f(s);
                return s.i;
        }
https://godbolt.org/g/qaR9KU

Or, identically:
        int f()
        {
                S s = { 0 };
                s.f();
                return s.i;
        }

This has a lot of impacts in the QString, QByteArray and the containers, since 
they have out-of-line functions. So, can we have a way to do "really const"?

Is that [[pure]] ?

* not quite [[pure]] functions

That's again the same thing as above: so long as a non-const function wasn't 
called, the result of many const member functions is supposed to remain the 
same. But these functions do read from memory. Example:

        int i = s.indexOf('/');
        int j = s.indexOf('/');

i and j are guaranteed to be the same in our API, so long as the user did not 
violate our thread-safety conditions by writing to s from another thread.

* the case of qGlobalQHashSeed(): it always returns the same thing, but on the 
first call it may make I/O to get random data. So this function can't be 
[[pure]]...

* constexpr: as I said in std-proposals, I have asked Marc to sacrifice the 
constexprness of the QStringView's constructor taking a QChar* without length. 
This is not the only function in which we've had to do so; see qalgorithms.h 
for more.

[changing gears]
* QVariant: need to investigate std::any and what std::any can benefit from the 
Qt 5 improvements (Q{Sequential,Associative}Iterable, QObject covariance, 
etc.)

* QVariant & metatype id: (if not using std::any) we need a constant identifier 
for each type and we need the type's name. The constant identifier for us is an 
int, but we could probably use the typeinfo. The difficult part is actually 
getting the type's name, since std::typeinfo does not guarantee that it will 
readable. Even for the compilers we support, it's not easy to extract the type 
name. This may come from reflection.

* reflection: 'nuff said.

* PMFs: we're running into UBs when we try to use PMFs as identifiers for 
signals.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list