I see Q_NULLPTR
being used liberally in Qt source code and examples, but I have found no documentation for what it is exactly and when it should be used.
For example in this official demonstration of the new Qt SerialBus module added in the new Qt v5.6:
if (!m_canDevice->connectDevice()) {
delete m_canDevice;
m_canDevice = Q_NULLPTR;
Did this serve the purpose of nullptr
prior to that being added in C++11? If so, now that we have C++11, should I be using Q_NULLPTR
?
PS: I tried searching the Qt source code for the definition of the macro but failed to find it.
Did this serve the purpose of nullptr prior to that being added in
C++11? If so, now that we have C++11, should I be using Q_NULLPTR?
Yes (somewhat) and No respectively.
C++ was quite lacking back in the days, so Qt had its own stuff, which later became obsolete as C++ caught up on the features.
That being said, Q_NULLPTR
is (was) not functionally the same as nullptr
, (as Andrei noted, if C++11 is supported it expands to nullptr
) it didn't give you the type safety, just syntax "sugar". It illustrated the intent to the person reading the code, not to the compiler as nullptr
does.
Q_NULLPTR
is a macro, that is replaced as nullptr
if compiler supports c++11 and as NULL
(which is replaced as 0
) if it doesn't. If you use c++11, you can write nullptr
instead; use NULL
if you don't.
Use Q_NULLPTR
to stay compiler independent.
If you now decide to use nullptr
, your code won't compile with an older c++98 compiler. If you decide to use NULL
, you lose the c++11 type safety, even if available in your current compiler.
For the same reason macros like qMove(x)
and the corresponding define Q_COMPILER_RVALUE_REFS
exists.
Actually Q_NULLPTR
had only one purpose: To allow use of nullptr
without loosing support for compilers which didn't have C++11/C++0x support, as a direct use of nullptr
would result in errors in such setups. The downside is that there are ambiguities of its fallback to NULL
(or 0
in older Qt versions) which might result in unintended runtime behavior and limit the supported use cases compared to nullptr
.
In the rare case that you target non C++11 compliant compilers, use Q_NULLPTR
but make sure that the code works well when C++11 features are disabled. In all other situations nullptr
is the better alternative as it results in compilation errors instead of buggy runtime behavior when used with legacy compilers. Qt 5.7 and later dropped the support for compilation without C++11 so there is no need for Q_NULLPTR
if you depend on those versions.
There are other features like qMove
or Q_DECL_OVERRIDE
that give improved semantic when used on supporting compilers without breaking compilation on older compilers.