User Tools

Site Tools


coding_guidelines

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
coding_guidelines [2019/06/17 19:58]
haslersn [Code Formatting]
coding_guidelines [2020/02/05 16:46] (current)
tapir [Line Widths] Broken lines indent
Line 86: Line 86:
 ===== Line Widths ===== ===== Line Widths =====
  
-Please configure your editor to have a max column-width of 80-columns. While it is not a strict requirement,​ 80-column cleanliness makes it easy to tile multiple buffers of code across a laptop screen, which provides significant efficiency gains to developers. Use double indent (8-spaces) for broken lines or align with the opening "​("​ in the line above for hanging indents.+Please configure your editor to have a max column-width of 80-columns. While it is not a strict requirement,​ 80-column cleanliness makes it easy to tile multiple buffers of code across a laptop screen, which provides significant efficiency gains to developers. 
 + 
 +For Mixxx'​s clang-format compatibility (ColumnLimit:​ 0):  
 +  * Use double indent (8-spaces) for broken lines 
 +  * Break line after binary operators.  
 +  * If you break a list of function parameters, put each parameter on a single ​line.  
  
  
Line 472: Line 477:
     * ''​parented_ptr''​ for ownership by the QT object tree: e.g. ''​auto p = make_parented<​T>​(...)''​     * ''​parented_ptr''​ for ownership by the QT object tree: e.g. ''​auto p = make_parented<​T>​(...)''​
  
-  * Pass raw pointer ''​T*''​ if no ownership is transfered. A function which receives a raw pointer should not hold onto the pointer ​outside the scope of the function (e.g. by storing it in a member variable). An exception is the parent pointer passed into the constructor of a ''​QObject''​ and internally stored as a non owning ​reference. Do not pass smart pointers by reference. ​+  * Pass reference ''​const T&''​ or ''​T&''​ if no ownership is transfered. ​Pass raw pointer ​''​const T*''​ or ''​T*''​ if no ownership is transfered ​and ''​nullptr''​ is a valid argument value. A function which receives a reference or raw pointer should not hold onto it outside the scope of the function (e.g. by storing it in a member variable). An exception is the parent pointer passed into the constructor of a ''​QObject''​ and internally stored as a non owning reference.
  
-  * ''​parented_ptr''​ requires the parent to be passed into the constructor at the time of creation. If a pointer that will eventually be managed ​by the QT object tree needs to be temporarily created without a parent, first create the object ​''​p'' ​with ''​std::​make_unique''​, and then later create a new variable using ''​parented_ptr(p.release())''​ once the underlying object gets a parent.+  * Pass smart pointers ​by value if ownership is transfered (''​std::​unique_ptr''​) or shared (''​std::​shared_ptr''​)Do not pass smart pointers by reference.
  
-  * Never store a ''​parented_ptr'' ​in an object ​that outlives the parent. If the lifetime of the child relative to the parent ​is not clear then store the output of ''​parented_ptr::​toWeakRef()'' ​instead.+  * Use ''​make_parented''​ to create objects derived from ''​QObject''​ that will be assigned to a parent ​(and will therefore be managed by the Qt object tree). The created object must get a parent ​before ​the ''​parented_ptr'' ​is destructedExample:
  
-  ​Any exceptions ​to these guidelines must be clearly documented inline in the code+    auto pBrowseButton = make_parented<​QPushButton>​(tr("​Browse"​));​ 
 +    // *pBrowseButton is not assigned ​to a parent yet 
 +    pLayout->​addWidget(pBrowseButton);​ 
 +    // Now *pLayout is the parent
  
 +  * The destructor of ''​parented_ptr''​ asserts that the pointed-to object actually has a parent. This ensures that the pointed-to object isn't leaked. A consequence is that **a ''​parented_ptr''​ must never dangle**. Never store a ''​parented_ptr''​ in an object that outlives the parent. This is most easily done by storing the ''​parented_ptr''​ inside exact the parent. If the lifetime of the pointer relative to the parent is not clear then store the output of ''​parented_ptr::​toWeakRef()''​ instead of a ''​parented_ptr''​.
 +
 +  * Any exceptions to these guidelines must be clearly documented inline in the code.
  
 ===== Assertions ===== ===== Assertions =====
Line 504: Line 515:
 </​code>​ </​code>​
  
-               +===== QString ===== 
 + 
 +Use [[http://​doc.qt.io/​qt-5/​qstring.html#​QStringLiteral|QStringLiteral]]. This has a variety of [[https://​woboq.com/​blog/​qstringliteral.html|benefits]].  
 + 
 +Escape non ASCII characters:  
 + 
 +<code cpp-qt>​ 
 +QStringLiteral("​Hello I\u2019ve to go"​);​ 
 +</​code>​ 
 + 
 +QChars can be initialized with ASCII characters 16 bit Unicode L’\u00fc'​ if required. Both are constexpr.  
 + 
 +<code cpp-qt>​ 
 +constexpr QChar kc = '​c'​ 
 +constexpr QChar kue = L'​\u00fc'​ // for "​ü"​ 
 +</​code>​ 
 + 
 +From Mixxx 2.3 we set QT_USE_QSTRINGBUILDER to use QStringBuilder for operator+. Use + in favour of % for better readability. ​         ​
  
  
Line 516: Line 544:
  
  
-===== C++14 =====+===== C++17 =====
  
-As of the Mixxx 2.3 release, Mixxx is switching to C++14. We are taking a conservative approach to adopting C++11/14 features and whitelisting them one by one. If a C++11/14 feature you would like to use is not listed here, please email mixxx-devel to make a case for it and we will consider whitelisting it.+As of the Mixxx 2.3 release, Mixxx is switching to C++17. We are taking a conservative approach to adopting C++11/14/17 features and whitelisting them one by one. If a C++11/14/17 feature you would like to use is not listed here, please email mixxx-devel to make a case for it and we will consider whitelisting it.
  
 We are limited to what is supported across our 3 supported compilers: We are limited to what is supported across our 3 supported compilers:
Line 575: Line 603:
 Use. Use.
  
-==== unicode string literals ==== 
  
-**Do Not Use**. Once we switch to Qt5, you should use [[http://​doc.qt.io/​qt-5/​qstring.html#​QStringLiteral|QStringLiteral]]. This has a variety of [[https://​woboq.com/​blog/​qstringliteral.html|benefits]]. ​ 
  
 ==== right angle brackets ==== ==== right angle brackets ====
Line 591: Line 617:
 In contrast to the pre-C++11 rules (see above) when using //​override//​ on a function in a derived class it is recommended to omit the redundant //virtual// keyword, because //​override//​ implies //​virtual//​. In contrast to the pre-C++11 rules (see above) when using //​override//​ on a function in a derived class it is recommended to omit the redundant //virtual// keyword, because //​override//​ implies //​virtual//​.
  
-Destructors in derived classes should also be marked with //​override//​ instead of //​virtual//​. This ensures at compile time that the base class has declared a //virtual// destructor. If the base class has not declared a //virtual// destructor the destructor of a derived class might not be invoked.+Destructors in derived classes should also be marked with //​override//​ instead of //​virtual//​. This ensures at compile time that the base class has declared a //virtual// destructor. If the base class has not declared a //virtual// destructor the destructor of a derived class might not be invoked. This applies also for default destructors even if it looks noisy
  
 +<code cpp-qt>
 +~ClassName() override = default;
 +</​code>​
 ==== alignment ==== ==== alignment ====
  
coding_guidelines.1560815929.txt.gz · Last modified: 2019/06/17 19:58 by haslersn