[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