Qt-In-Namespace: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
No edit summary
(redirect)
 
Line 1: Line 1:
[[Category:Developing_Qt::Guidelines]]
#REDIRECT [[Qt In Namespace]]
 
= Qt in Namespace =
 
The Qt-in-Namespace feature serves as a tool to handle certain scenarios involving multiple configurations of Qt more gracefully. E.g. before Qt-in-Namespace a Qt 3 based application in Linux would immediately segfault as soon as it tries to dlopen() a shared object that is linked to Qt 4. With the Qt in namespace feature not only can the crash be prevented, but under certain circumstances this combination might actually "work".
 
The core of the feature's implementation consists of wrapping "all of Qt code" into a pair of macros <code>QT_BEGIN_NAMESPACE</code> and <code>QT_END_NAMESPACE</code>. Both macros usually expand to nothing, but they expand to "namespace xxx {" and "}", respectively, when Qt is configured with the option "-qtnamespace xxx"". The macros are defined in <code><qglobal.h></code>
 
The feature is part of Qt since Qt 4.4. Keeping the feature in a working state is, unfortunately, a bit tedious and influences code that gets integrated into Qt.
 
To help with this, all contributors to the Qt source code are kindly asked to follow the set of rules given below.
 
=== Rules for ''namespaced'' code: ===
 
This concerns code in <code>main/src/{corelib,gui,…}</code> and in <code>main/tools/designer</code> but not in <code>main/src/3rdparty</code>. As a rule of thumb: If it contributes to one of "the Qt" libraries that end up in <code>lib/*</code> ''and'' if it is "Qt" code, it is "namespaced code".
 
# All occurrences of <code>QT_BEGIN_NAMESPACE</code> and <code>QT_END_NAMESPACE</code> must be balanced with respect to <code>#if/#ifdef</code> etc. preprocessor directives. Most notably this applies to all <code>QT_NO_<FEATURE></code> branches.
# All code that is not a preprocessor directive or a comment must be wrapped in <code>QT_BEGIN_NAMESPACE</code> and <code>QT_END_NAMESPACE</code>. As a rule of thumb this applies do all definitions and declarations concerning types, objects etc with identifiers starting with 'q' or 'Q'.
# All <code>#include</code> lines go outside the <code>QT_BEGIN_NAMESPACE … QT_END_NAMESPACE</code>.
# Forward declarations of items in non-namespaced code go outside.
# As a special exception <code>QT_DECLARE_METATYPE</code> lines go ''outside''.
# <code>Q_INIT_RESOURCE</code> inside. However, the Makefile dependencies are inadequate, so make sure to remove all qrc_'''.cpp files manually if you have troubles when "namespacing" old code.
# If we are in a header file there is usually already a <code>QT_{BEGIN,END}''HEADER</code> pair (or needs to be added) for other reasons. In this case <code>QT_BEGIN_NAMESPACE</code> follows immediately the <code>QT_BEGIN_HEADER</code> line, and <code>QT_END_NAMESPACE</code> precedes the <code>QT_END_HEADER</code> line. To be consistent in style with existing code there should be a single empty line between the <code>QT''{BEGIN,END}''HEADER</code> and <code>QT''{BEGIN,END}''NAMESPACE</code> lines.
# Since not all compilers we support adhere to The Standard we cannot use namespaced friend classes within some other class definition without declaring the friend class properly first. As a workaround, declare the friend class first within a <code>QT''{BEGIN,END}_HEADER block</code>.
# Since not all compilers we support adhere to The Standard we cannot declare external functions locally within other functions. As a workaround, declare the external function on namespace scope.
 
h3. Rules for ''namespace aware'' code:
 
This concerns everything in <code>main/'''</code> that is not "namespaced code" and any end user code that wishes to use the Qt-in-Namespace feature:
 
# All forward declarations of types, functions and objects that are in "namespaced code" must be namespaced and their use must be "namespace qualified", i.e. written as
 
<code>
QT_BEGIN_NAMESPACE
class QCheckBox;
class QComboBox;
QT_END_NAMESPACE
</code>
 
This is admittedly ugly but needed. A simple <code>using namespace QT_NAMESPACE</code> unfortunately does not help as
 
<code>
namespace QT_NAMESPACE { … }
using namespace QT_NAMESPACE;
class QString;
</code>
 
will declare QString at global namespace which will be distinct from our <code>QT_NAMESPACE::QString</code> and cause compiler or linker errors later.
 
* A <code>QT_BEGIN_NAMESPACE</code> and <code>QT_END_NAMESPACE</code> wrapper is also needed when extending a namespace that itself lives in namespaced code. This situation typically appears when extending the QtTest namespace in auto tests.
 
Making code ''namespace aware'' can be given a headstart by running
 
<code>
find . -name ''''.cpp' -o -name ''''.h' -exec perl -pie 's:^class Q (.*);:QT_ADD_NAMESPACE_PREFIX($1);: {}
</code>
 
but it looks a bit cleaner if only <code>QT_BEGIN_NAMESPACE</code> and <code>QT_END_NAMESPACE</code> are used.
 
=== Rules for other code: ===
 
Everything else including end user code that does not need the feature and end user code that is not even aware of Qt at all does not need to be changed.
 
=== Related: ===
 
The [[Category:Tools::QtCreator|Qt Creator]]Debugger can handle namespaced code as if it were "native" Qt.

Latest revision as of 11:10, 27 February 2015

Redirect to: