[Development] Namespaces (was: Qt Platform Extras)

Sze Howe Koh szehowe.koh at gmail.com
Sun Sep 22 07:21:34 CEST 2013


Hi,


>From the current API, namespaces feel haphazardly implemented. I'd
like to work on making namespaces part of the Qt coding style guide,
to aid future API reviews. Documentation should be included in this
discussion too, as a standardized layout makes it easier for a
newcomer to find the API they need.

Below, I'm trying to present the discussions and suggestions from
previous emails (plus some new ones) in a "big-picture" view of the
topic. Some suggestions are mutually exclusive, but all are presented
to aid in the selection of the "best" set of policies. Please add your
thoughts on how namespaces should be used in Qt going forward, and add
any other points we should consider.

Further below, I'm responding to some issues raised by Thiago's last
email on the topic.



// ========================
//  SCOPE
// ========================
// POINTS TO CONSIDER:
* Currently released namespaces hold functions, types, and macros that
don't belong to a particular stateful class.

* Currently released namespaces don't hold classes, except for one:
QTest::QTouchEventSequence

* QtWin's counterpart is QX11Info. Yet, the former is implemented as a
namespace, the latter a class.

* Aside from the namespaces we've been discussing recently, there is
another kind of namespace in unreleased modules. These are associated
with the Q_BEGIN_NAMESPACE_<MODULE> macros. They cover everything in
the module, including classes and other namespaces (e.g. QtOrganizer,
QtBluetooth, QtNfc)

* QtBluetooth and QtNfc were recently removed in preparation for the
modules' Qt 5.2 release

* The Qt NFC module exports a standalone public function,
qNfcChecksum(). It is currently in the global namespace. (There might
be others; I didn't search in depth)


// PROPOSALS:
+ Prefer namespaces over stateless classes (thinking of QX11Info)

+ All standalone module functions should be placed in a namespace
(thinking of qNfcChecksum())


// QUESTIONS:
? Will we ever want more namespaced classes?

? What is the Qt Project's position on Q_BEGIN_NAMESPACE_<MODULE>?



// ========================
// NAMING CONVENTIONS
// ========================
// POINTS TO CONSIDER:
* Currently, most namespaces look like classes and have "QFoo" names.

* The basic proposal that has been around for a while is to have
module-wide namespaces named identically to their owning library, e.g.
"QtConcurrent".

* However, "QtWindowsExtras" is too long. People want the shorter "QtWin".


// PROPOSALS:
+ Make all new Qt 5 namespaces "QFoo" to match current namespaces.
Change everything together in Qt 6.

+ Make all new Qt 5 namespaces "QtFoo" to start using the new scheme.
Change the old ones in Qt 6.

+ Use different conventions for module-wide (QtFoo) and
non-module-wide (QFoo) namespaces


// QUESTIONS:
? What's the definition/criteria for "module-wide"? (discussed more below)

? What kind of boundaries (if any) do we want, so that namespaces
don't deviate too much from their owning library? (thinking of QtWin)

? If not all module-wide namespaces are named after their owning
libraries (thinking of QtWin), is there still any value in changing
"QFoo" to "QtFoo"?



// ========================
// HEADER CONVENTIONS
// ========================
// POINTS TO CONSIDER:
* For most part, headers are named identically to the class/namespace
they contain. This makes it nice and easy for users to remember which
header to include.

* Current QtFoo namespaces don't match that pattern. It would be good
to standardize them.

* QtConcurrent is split across 3 headers: <QtConcurrentMap>,
<QtConcurrentFilter>, <QtConcurrentRun>

* QtWin uses <QWinFunctions>

* Currently, headers that are named after libraries pull in every
single function, type, class, etc. in a module. This can be bad for
compilation times.


// PROPOSALS:
+ Treat large includes as a non-issue, and ask users to include the
whole module to use the QtFoo namespace

+ Push for the use of .pch files to make large includes cost nothing,
and ask users include the whole module to use the QtFoo namespace

+ Remove the full-module headers and let the QtFoo namespaces use <QtFoo>

+ Keep the full-module headers and give QtFoo namespaces a standard
format, e.g. <QtFooNamespace>



// ========================
// DOCUMENTATION
// ========================
// POINTS TO CONSIDER:
* QDoc auto-links library names (e.g. QtGui, QtConcurrent) to the
module's "C++ Classes" page. This is a relic from pre-QML days and
should be changed, even if namespaces don't change.

* The Qt Concurrent docs are a mess -- links that should take users to
the QtConcurrent namespace page go to the "Qt Concurrent C++ Classes"
page instead.

* QDoc should be updated before a new naming scheme is introduced, or
doc navigation could become an unpleasant user experience.

* The documentation team prefers module names (e.g. "Qt GUI", "Qt
Concurrent") over library names (e.g. "QtGui", "QtConcurrent") in the
text, as the former are considered better product names. So, most
library names have been replaced -- we don't need to auto-link library
names any more.


// PROPOSALS:
+ Stop auto-linking to "C++ Classes" pages. This will let QDoc
auto-link "QtFoo" namespaces correctly.



On 17 September 2013 21:38, Thiago Macieira <thiago.macieira at intel.com> wrote:
> On terça-feira, 17 de setembro de 2013 18:30:32, Sze Howe Koh wrote:
>> > I think I agree with JP. AFAICS, no other module is using module-wide
>> > namespaces, so it would not be inconsistent to name it QtFoo.
>> Actually, there are 5 such module-namespace pairs:
>>     * Qt D-Bus -- QDBus
>>     * Qt Multimedia -- QMultimedia
>>     * Qt OpenGL -- QGL
>>     * Qt SQL -- QSql
>>     * Qt Test -- QTest
>>
>> The odd one out is:
>>     * Qt Concurrent -- QtConcurrent
>
> Of those 5 you listed, only QtTest / QTest is a module-wide namespace. The
> QDBus module contains just a couple of constants, just like QSql. The classes
> themselves are not inside the namespace and there are no functions inside the
> namespace either.
>
> QtConcurrent, on the other hand, is a very good example of a module-wide
> namespace.

First, may I ask what's the definition/criteria for a "module-wide
namespace"? From your last email, I think you meant "It covers
everything that the module offers". But in reality, including QTest,
QtConcurrent and QtWin while excluding the others uses these criteria:
    * It contains standalone functions, and
    * The number of classes outside the namespace isn't too big

There are classes outside QTest (QSignalSpy, QTestEventList) and QtWin
(which contains none of the module's 6 classes). Also, while QSql only
contains a few enums, those enums are core to the functionality of the
whole module. Either all 3 are "module-wide", or none of them are.

Also, suppose the Qt Concurrent module gains some complex classes, and
the Qt Multimedia module gains some standalone functions. If we follow
existing conventions, would you agree that the classes should go
OUTSIDE the QtConcurrent namespace, while the functions should go
INSIDE the QMultimedia namespace? Would this affect the namespaces'
"module-wide" status?


>> > Also, using QtFoo makes it consistent with the module-wide include:
>> > #include <QtFoo>
>> >
>> > (And it cannot be #include <QFoo> since that would be inconsistent with
>> > our other module-wide includes)
>> The headers for the namespaces listed above are:
>>     #include <QMultimedia>
>
> Just a few constants, not equivalent to <QtMultimedia>
>
>>     #include <QSql>
>
> Just four enums, no classes, not equivalent to <QtSql>.
>
>>     #include <QTest>
>
> This is the only one that is equivalent to <QtTest>.

Are they intended to be equivalent?

The QSignalSpy class is not in the QTest namespace, and isn't
available through <QTest>. It's available through <QtTest> or
<QSignalSpy>.

Should a header that's named after a namespace contain classes that
aren't part of the namespace? (No, IMHO)


>>     #include <QDBus>
>
> Doesn't exist.
>
>>     #include <QGL>
>
> Doesn't exist.

Right. Something needs fixing then. What's the preferred fix?
(a) Remove those headers from documentation (e.g.
http://qt-project.org/doc/qt-5.1/qtdbus/qdbus.html), or
(b) Add those headers to sync.profile?

I'm leaning towards (a) since the enums in those namespaces are used
in conjunction with other module classes.


>>     #include <QtConcurrentMap>, #include <QtConcurrentFilter>,
>> #include <QtConcurrentRun>
>> (The QtConcurrent namespace is split across different headers)
>
> None of those includes are official.

Those headers have been officially documented since Qt 4, e.g.
http://qt-project.org/doc/qt-5.1/qtconcurrent/qtconcurrentmap.html

The <QtConcurrent(Map|Filter|Run)> triplet doesn't fit at all with the
rest of Qt's header scheme though. I'm happy to rewrite the
documentation to make <QtConcurrent> the official header, and mark the
triplet for removal in Qt 6. Would you support such a move?


>> These namespace includes are NOT the same as module-wide includes. I
>> think module-wide includes should only ever be used for rapid
>> prototyping. We should make it possible to use a namespaced function
>> without pulling in every other class in the module.
>>
>> Example:
>> #include <QMultimedia> pulls in the QMultimedia namespace only, but
>> #include <QtMultimedia> pulls in the QMultimedia namespace PLUS all
>> the audio, video, radio, camera etc. classes. This can adversely
>> impact compilation times for large projects.
>>
>> If we want to start using QtFoo namespaces, I think we should also
>> decide on a new (and universally-applicable) header scheme. Maybe
>> #include <QtFooNamespace>?
>
> That is a very good point. If the namespace name is the same as the module
> name, then you can only include the entire module if you try to get the
> namespace.
>
> The question is: is that so bad? I don't think so. If such a module grows, you
> can always include the individual classes instead of the module-wide include.

My concern was more for the namespaced functions. Classes always have
their own dedicated headers, so there's no issue here. But, suppose
that the number of classes in Qt Windows Extras grows substantially,
and I just want to use QtWin::toHICON() -- it would be nice to have a
header dedicated to the namespace, so I don't have to include the
classes that I don't need.


Regards,
Sze-Howe



More information about the Development mailing list