[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