[Development] Qt 6: inline namespace Qt
Vitaly Fanaskov
vitaly.fanaskov at qt.io
Fri Sep 6 13:25:18 CEST 2019
Hi Marc,
Could you elaborate a bit, what the real value of this change?
I'm asking, because there are only cons I see now:
1) Adding inline after namespace *implicitly* throws all symbols to the
global (or outer) namespace, which, potentially might lead to name
clashes. For example, the following code won't be compiled:
inline namespace foo { void bar() {} };
void bar() {}
// ...
bar();
2) Negative user experience especially when moving to a fresh Qt
version: some names are implicitly appears.
3) Potentially force users to compile Qt in a namespace. This is not
required in a lot of cases, really. One of the cases might be when your
app is a plugin and a host app also uses Qt of the same version. But
it's rarely.
On 9/6/19 11:26 AM, Mutz, Marc via Development wrote:
> 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
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> https://lists.qt-project.org/listinfo/development
--
Best Regards,
Fanaskov Vitaly
Senior Software Engineer
The Qt Company / Qt Quick and Widgets Team
More information about the Development
mailing list