[Development] Upgrading the sources to C++11 keywords (Q_NULLPTR, etc.)
Ziller Eike
Eike.Ziller at theqtcompany.com
Mon Jan 12 08:36:35 CET 2015
> On Jan 9, 2015, at 10:10 PM, Thiago Macieira <thiago.macieira at intel.com> wrote:
>
> On Friday 09 January 2015 20:19:36 André Pönitz wrote:
>> In some case these macros even expand to something else than the "obviously
>> related" C++ keyword, so potential benefits gained from using the actual
>> feature have to be weighed with the costs of obfuscation.
>
> They expand to the correct keyword when the keyword is permitted, so there's
> no mistake. They expand to something else that will not affect the code unduly
> if the keyword is not permitted.
>
> Do you have anything in mind for when they'd expand unexpectedly?
>
>>> I'd like to propose the following.
>>>
>>> Policy per keyword:
>>> * Q_NULLPTR - strongly encouraged
>>>
>>> Use it whenever your literal zero is a null pointer. You can leave it out
>>> when it cannot be mistaken for a zero and it would otherwise make the
>>> source code harder to read.
>>>
>>> Note that Qt still compiles with C++98, so you can't use Q_NULLPTR for
>>> disambiguation.
>>
>> No, please, not.
>>
>> C++ 'nullptr' only gives a benefit over '0' in the rare cases where it
>> helps for disambiguation. I would not really like a policy encouraging
>> 'nullptr' when '0' is just fine, but at least that would be tolerable.
>>
>> On the other hand, 'Q_NULLPTR' does not even serve the 'disambiguation'
>> purpose, so it's really useless annoying line noise.
>>
>> I propose to continue to use '0' until Qt can switch over to C++11
>> and then re-open the discussion with 'nullptr - mildly encouraged'.
>
> Fair enough.
>
> Marc, what's your opinion?
>
> Note that the disambiguation need not be only by the compiler. If the code is
> simpler to understand because you marked something as a pointer, then I think
> you should use the macro.
>
>>> * Q_DECL_FINAL - optional, use with care
>>>
>>> There's a small benefit in optimisation by devirtualising calls. Use it
>>> with care.
>>>
>>> Use in public classes is discouraged, since people can compile with a
>>> C++98
>>> and derive / override what they shouldn't.
>>
>> Another reason is that even if "we" think it should be final, the user of
>> the class (or rather sub-classes) might disagree.
>
> We make the call because we designed the code. If the class isn't intended to
> be derived from, then let the user know.
Not sure what you have in mind here concretely.
But q_decl_final is definitely not just a “hint” that lets the user know that the class was not intended to be derived from, it prevents deriving.
Even though I agree that you should generally not derive from a class that was not intended for it,
this also blocks the occasionally useful violation of that rule, e.g. for working around Qt bugs.
> * Q_DECL_OVERRIDE - required in new code, don't add to old code
>>>
>>> Always add Q_DECL_OVERRIDE for any override in new classes you write. This
>>> supersedes the need for the "virtual" keyword -- add it or not, it's up to
>>> you.
>>>
>>> DO NOT add to existing classes, including for new overrides to existing
>>> classes. Clang 3.6 has a new warning about inconsistent use of this
>>> keyword, so adding to one place requires adding to all overrides in that
>>> class. Therefore, this needs to be done fully in each class and that's
>>> not a "whitespace correction" error.
>>
>> In my opinion Q_DECL_OVERRIDE brings sufficient benefit to generally
>> encourage its use despite of the line noise it brings. However, since
>> 'virtual' is not needed in case Q_DECL_OVERRIDE is used the rule should be
>> to leave 'virtual' out/remove it in that case.
>
> Indeed.
>
>> [1] - All 'ok' under the assumption that this does not affect code that
>> does not need to stay compatible with C++98. Such code should rather use
>> C++11 keywords directly.
>
> That's still per compiler, since compilers added support for the keywords at
> different times. Therefore, the use of the Q macro is required, unless you've
> already surrounded the code with the matching #ifdef.
>
> For example:
>
> #if defined(Q_COMPILER_CONSTEXPR) && defined(Q_COMPILER_UNIFORM_INIT)
> constexpr Foo() : array{1, 2, 3} ()
> #endif
>
> --
> Thiago Macieira - thiago.macieira (AT) intel.com
> Software Architect - Intel Open Source Technology Center
>
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
--
Eike Ziller, Senior Software Engineer - Digia, Qt
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Tuula Haataja
Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 144331 B
More information about the Development
mailing list