[Development] Qt 6: inline namespace Qt
Mutz, Marc
marc at kdab.com
Fri Sep 6 11:26:43 CEST 2019
Hi,
I would like to propose to make the existing Qt namespace inline and
move all of Qt's declarations into it.
== TL;DR: ==
Qt can already, optionally, be configured into a user-specified
namespace (QT_BEGIN_NAMESPACE/QT_END_NAMESPACE, -qtnamespace), and this
is one of the build configurations in the CI, so we're reasonably sure
it works. The change would be very limited (via existing macros). Only
pre-existing declarations of "namespace Qt" would have to be touched.
The change is SC, and makes namespaced and non-namespaced builds behave
the same.
== Rationale ==
As we see with the introduction of Qt::endl, a SiC change, we have a
problem in that we have existing Qt API that traditionally (dare I say
"for decades") doesn't have a Q/q prefix. Adding Qt:: in front now is a
massive SiC change. Making the Qt namespace inline allows users to
continue to write << endl; while we still have the symbol moved out of
the global namespace.
Furthermore, the global namespace is special in that ADR does "not work
in it"[1]; [1] can be summarized as "C++ just works better when all
types are in some namespace". This means that we have very subtle
differences in name lookup, depending on whether Qt is compiled with
-qtnamespace or without. I remember having hit these multiple times in
the past, but can't remember details anymore (and one or the other might
have had to do more with two-phase name lookup in templates, and not
with ADR).
[1]
https://groups.google.com/forum/#!msg/comp.lang.c++.moderated/1Qz71aFnXlI/Gd71gwRaWssJ
The language has also started stipulating in a few places that certain
functions are only found via ADR, not by ordinary name lookup (the
begin() and end() functions called by ranged-based loop for non-array
types that don't have a .begin()/.end() come to mind). There seems to be
some confusion[2] over whether that means that functions in the global
namespace would be found at all under such circumstances (I guess Ville
could confirm or deny), and vice versa: when functions are defined as
friends in the body of types (in which case they're only found via ADL
and not via ordinary name lookup) in the global namespace, do they exist
at all? But we can do very well without such dipping into C++'s dark
corners: if we are always in a namespace, ADL always works.
[2]
https://stackoverflow.com/questions/25133383/does-adl-work-for-the-global-namespace
Thus, I'd like to propose to move all of Qt into an inline namespace Qt.
Any user namespace would be wrapping it:
inline namespace Qt {
class QString;
}
without `-qtnamespace` and
namespace TestNamespace {
inline namespace Qt {
class QString;
}
}
with `-qtnamespace TestNamespace`.
Because the namespace is inline, existing code will just have to be
recompiled to pick it up. In particular, no `using namespace Qt` is
needed anywhere to still use QString etc unqualified, yet, the
executable would refer to Qt::QString everywhere. Even
Q_DECLARE_TYPEINFO would continue to work unchanged, since you don't
need to open an inline namespace to specialise templates from it.
It's a BiC change, though, so it's for Qt 6.0, if ever.
== Design Decisions ==
=== inline Qt::Qt3D or inline Qt3D ? ===
Some Qt modules have started using a (non-inline) namespace, often
derived from the module or library name, since Qt 4 (QtPatternist,
QtConcurrent, Qt3D, ...). A legitimate design would leave the Qt
namespace alone, and put each library Lib into an inline namespace QtLib
instead. This would solve the same problems, and could be used to unify
the different libraries' choices of handling naming. The reason that
it's not proposed here is that it's a much grander scheme than just
wrapping everything into `inline namespace Qt` - all the Qt modules are
already known to work with the user namespace feature and this proposal
simply suggests to append `inline namespace Qt {` to QT_BEGIN_NAMESPACE
so that this macro always expands to at least one namespace begin.
Giving each module or library its own inline namespace would be much
more work.
Flame away :)
Thanks,
Marc
More information about the Development
mailing list