2010-12-21 14:02:05 +01:00
|
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2011-01-11 16:28:15 +01:00
|
|
|
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
2010-12-21 14:02:05 +01:00
|
|
|
|
**
|
|
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
|
|
|
|
**
|
|
|
|
|
** No Commercial Usage
|
|
|
|
|
**
|
|
|
|
|
** This file contains pre-release code and may not be distributed.
|
|
|
|
|
** You may use this file in accordance with the terms and conditions
|
|
|
|
|
** contained in the Technology Preview License Agreement accompanying
|
|
|
|
|
** this package.
|
|
|
|
|
**
|
|
|
|
|
** GNU Free Documentation License
|
|
|
|
|
**
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU Free
|
|
|
|
|
** Documentation License version 1.3 as published by the Free Software
|
|
|
|
|
** Foundation and appearing in the file included in the packaging of this
|
|
|
|
|
** file.
|
|
|
|
|
**
|
|
|
|
|
** If you have questions regarding the use of this file, please contact
|
|
|
|
|
** Nokia at qt-info@nokia.com.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
2008-12-11 13:23:03 +01:00
|
|
|
|
/*!
|
|
|
|
|
|
2011-01-05 12:07:24 +01:00
|
|
|
|
\contentspage{index.html}{Qt Creator}
|
2008-12-11 13:23:03 +01:00
|
|
|
|
\page coding-style.html
|
|
|
|
|
|
|
|
|
|
\title Qt Creator Coding Rules
|
|
|
|
|
|
|
|
|
|
THIS IS PRELIMINARY.
|
|
|
|
|
|
|
|
|
|
\section1 Introduction
|
|
|
|
|
|
|
|
|
|
The aim of this section is to serve as a guide for the developers, to aid us
|
|
|
|
|
to build understandable and maintainable code, to create less confusion and
|
|
|
|
|
surprises when working on Qt Creator.
|
|
|
|
|
|
|
|
|
|
As usual: Rules are not set in stone. If there's a good reason to break one,
|
|
|
|
|
do it, preferably after making sure that there are others agreeing.
|
|
|
|
|
|
|
|
|
|
This document is incomplete.
|
|
|
|
|
|
|
|
|
|
In general, if you want to contribute to the main source, we expect at least
|
|
|
|
|
that you:
|
|
|
|
|
|
|
|
|
|
\list 1
|
|
|
|
|
\o The most important rule first: KISS (keep it simple ...): always
|
|
|
|
|
use a simple implementation in favor of a more complicated one.
|
|
|
|
|
This eases maintenance a lot.
|
|
|
|
|
\o Write good C++ code: Readable, well commented when necessary,
|
|
|
|
|
and taking advantage of the OO model. Follow the \l{Formatting} guidelines.
|
|
|
|
|
There are also certain \l{Code Constructs} that we try to follow.
|
|
|
|
|
\o Adapt the code to the structures already existing in Qt Creator, or in
|
|
|
|
|
the case that you have better ideas, discuss them with other developers
|
|
|
|
|
before writing the code.
|
2011-01-05 12:07:24 +01:00
|
|
|
|
\o Follow the \l{Patterns and practices} that we use in Qt Creator.
|
2008-12-11 13:23:03 +01:00
|
|
|
|
\o Take advantage of Qt. Don't re-invent the wheel. Think about what parts
|
2010-01-29 21:33:57 +01:00
|
|
|
|
of your code are generic enough that they might be incorporated into
|
|
|
|
|
Qt proper.
|
2008-12-11 13:23:03 +01:00
|
|
|
|
\o Document interfaces. Right now we use qdoc, but changing to doxygen
|
|
|
|
|
is being considered.
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section1 Submitting Code
|
|
|
|
|
|
2010-01-22 13:49:32 +01:00
|
|
|
|
See http://qt.gitorious.org/qt/pages/QtContributionGuidelines
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
|
|
|
|
\section1 Code Constructs
|
|
|
|
|
|
|
|
|
|
We have several guidelines on code constructs, some of these exist to
|
|
|
|
|
make the code faster, others to make the code clearer. Yet others
|
2011-02-04 15:16:27 +01:00
|
|
|
|
exist to allow us to take advantage of the strong type checking in C++.
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
|
|
|
|
\list 1
|
|
|
|
|
\o Declaration of variables should wait as long as possible. The rule
|
|
|
|
|
is: "Don't declare it until you need it." In C++ there are a lot of
|
|
|
|
|
user defined types, and these can very often be expensive to
|
|
|
|
|
initialize. This rule connects to the next rule too.
|
|
|
|
|
|
|
|
|
|
\o Make the scope of a variable as small as possible.
|
|
|
|
|
|
|
|
|
|
\o Prefer preincrement to postincrement whenever possible.
|
|
|
|
|
Preincrement has potential of being faster than postincrement. Just
|
|
|
|
|
think about the obvious implementations of pre/post-increment. This
|
|
|
|
|
rule applies to decrement too.
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
++T;
|
|
|
|
|
--U;
|
|
|
|
|
-NOT-
|
|
|
|
|
T++; // not used in Qt Creator
|
|
|
|
|
U--; // not used in Qt Creator
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
\o Try to minimize evaluation of the same code over and over. This is
|
|
|
|
|
aimed especially at loops.
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
|
|
|
|
|
Container::iterator end = large.end();
|
|
|
|
|
for (Container::iterator it = large.begin(); it != end; ++it) {
|
|
|
|
|
...;
|
|
|
|
|
}
|
|
|
|
|
-NOT-
|
|
|
|
|
for (Container::iterator it = large.begin();
|
|
|
|
|
it != large.end(); ++it) {
|
|
|
|
|
...;
|
|
|
|
|
}
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
|
2010-01-29 21:33:57 +01:00
|
|
|
|
\o Using Qt's foreach is ok in non-time critical code when using a QTL
|
2008-12-17 15:03:23 +01:00
|
|
|
|
container. It is a nice way to keep line noise down and to give the
|
|
|
|
|
loop variable a proper name:
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
foreach (QWidget *widget, container)
|
|
|
|
|
doSomething(widget);
|
|
|
|
|
|
|
|
|
|
-VS-
|
|
|
|
|
|
|
|
|
|
Container::iterator end = container.end();
|
|
|
|
|
for (Container::iterator it = container.begin(); it != end; ++it)
|
|
|
|
|
doSomething(*it);
|
|
|
|
|
\endcode
|
2010-01-29 21:33:57 +01:00
|
|
|
|
|
|
|
|
|
If the loop variable can be made const, do so. This can prevent
|
2008-12-17 15:03:23 +01:00
|
|
|
|
unnecessary detaching of shared data in some cases. So:
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
foreach (const QString &name, someListOfNames)
|
|
|
|
|
doSomething(name);
|
2010-01-29 21:33:57 +01:00
|
|
|
|
|
2008-12-17 15:03:23 +01:00
|
|
|
|
- NOT -
|
|
|
|
|
|
|
|
|
|
foreach (QString name, someListOfNames)
|
|
|
|
|
doSomething(name);
|
|
|
|
|
\endcode
|
|
|
|
|
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
|
|
|
|
\section1 Formatting
|
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
\section2 Naming rules
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
\list
|
|
|
|
|
\o Class names are capitalized, and function names lowercased.
|
|
|
|
|
\o Variables and functions start with a lower case letter.
|
|
|
|
|
\o Enums are named like Classes, values are in loweri case, containing
|
|
|
|
|
some part of the name of the enum type.
|
|
|
|
|
\endlist
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
|
|
|
|
|
\section2 Declaration of variables
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
\o Each consecutive word in a variable's name starts with a capital letter.
|
|
|
|
|
|
|
|
|
|
\o Avoid short (e.g., a, rbarr, nughdeget) names whenever possible.
|
|
|
|
|
Single character variable names are only okay for counters and
|
|
|
|
|
temporaries, where the purpose of the variable is obvious.
|
|
|
|
|
|
|
|
|
|
\o Declare each variable on a separate line.
|
|
|
|
|
\code
|
|
|
|
|
QString a = "Joe";
|
|
|
|
|
QString b = "Foo";
|
|
|
|
|
-NOT-
|
|
|
|
|
QString a = "Joe", b = "Foo"; // not used in Qt Creator
|
|
|
|
|
\endcode
|
2010-01-29 21:33:57 +01:00
|
|
|
|
[Note that 'QString a = "Joe"' is formally calling a copy constructor
|
2008-12-11 13:23:03 +01:00
|
|
|
|
on a temporary constructed from a string literal and therefore has the
|
|
|
|
|
potential of being more expensive then direct construction by
|
2011-02-04 15:16:27 +01:00
|
|
|
|
'QString a("Joe")'. However the compiler is allowed to elide the copy
|
2008-12-11 13:23:03 +01:00
|
|
|
|
(even if it had side effects), and modern compilers typically do so.
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Given these equal costs, Qt Creator code favours the '=' idiom as
|
|
|
|
|
it is in
|
2008-12-11 13:23:03 +01:00
|
|
|
|
line with the traditional C-style initialization, _and_ cannot be
|
|
|
|
|
mistaken as function declaration, _and_ reduces the level of nested
|
|
|
|
|
parantheses in more initializations.]
|
2010-01-29 21:33:57 +01:00
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
\o Avoid abbreviations
|
|
|
|
|
|
|
|
|
|
// Wrong
|
|
|
|
|
int a, b;
|
|
|
|
|
char *c, *d;
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
int height;
|
|
|
|
|
int width;
|
|
|
|
|
char *nameOfThis;
|
|
|
|
|
char *nameOfThat;
|
|
|
|
|
|
|
|
|
|
\o Wait with declaring a variable until it is needed. This is especially
|
|
|
|
|
important when initialization is done at the same time.
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
|
|
|
|
\section2 Pointers and references
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
char *p = "flop";
|
|
|
|
|
char &c = *p;
|
|
|
|
|
-NOT-
|
|
|
|
|
char* p = "flop"; // not used in Qt Creator
|
|
|
|
|
char & c = *p; // not used in Qt Creator
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
Also note that we will have:
|
|
|
|
|
\code
|
|
|
|
|
const char *p;
|
|
|
|
|
-NOT-
|
|
|
|
|
char const * p; // not used in Qt Creator
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Using a plain 0 for Null pointer constants is always correct and
|
|
|
|
|
least effort to type. So:
|
2008-12-11 13:23:03 +01:00
|
|
|
|
\code
|
|
|
|
|
void *p = 0;
|
|
|
|
|
-NOT-
|
|
|
|
|
void *p = NULL; // not used in Qt Creator
|
|
|
|
|
-NOT-
|
|
|
|
|
void *p = '\0'; // not used in Qt Creator
|
|
|
|
|
-NOT-
|
|
|
|
|
void *p = 42 - 7 * 6; // also not used in Qt Creator
|
|
|
|
|
\endcode
|
|
|
|
|
Note: As an exception, imported third party code as well as code
|
|
|
|
|
interfacing the "native" APIs (src/support/os_*) can use NULL.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Operator names and parentheses
|
|
|
|
|
\code
|
|
|
|
|
operator==(type)
|
|
|
|
|
-NOT-
|
|
|
|
|
operator == (type) // not used in Qt Creator
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
The == is part of the function name, separating it makes the
|
|
|
|
|
declaration look like an expression.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Function names and parentheses
|
|
|
|
|
\code
|
|
|
|
|
void mangle()
|
|
|
|
|
-NOT-
|
|
|
|
|
void mangle () // not used in Qt Creator
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
\section2 Indentation
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Four spaces, no tabs.
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
\section2 Whitespace
|
2011-02-04 12:44:43 +01:00
|
|
|
|
\list
|
|
|
|
|
\o Use blank lines to group statements together where suited.
|
|
|
|
|
\o Always use only one blank line.
|
|
|
|
|
\o Always use a single space after a keyword, and before a curly brace.
|
|
|
|
|
\endlist
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
if(foo){
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
if (foo) {
|
|
|
|
|
}
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
For pointers or references, always use a single space before '*' or '&',
|
|
|
|
|
but never after.
|
2008-12-15 17:48:02 +01:00
|
|
|
|
Avoid C-style casts when possible.
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
char* blockOfMemory = (char* ) malloc(data.size());
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
char *blockOfMemory = (char *)malloc(data.size());
|
|
|
|
|
char *blockOfMemory = reinterpret_cast<char *>(malloc(data.size()));
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
|
|
|
|
Of course, in this particulare case, using \c new might be an even better
|
|
|
|
|
option.
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
|
|
|
|
Braces
|
2011-02-04 12:44:43 +01:00
|
|
|
|
As a base rule, the left curly brace goes on the same line as the
|
|
|
|
|
start of the statement:
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
if (codec)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
if (codec) {
|
|
|
|
|
}
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Exception: Function implementations and class declarations always have
|
|
|
|
|
the left brace on the start of a line:
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
static void foo(int g)
|
|
|
|
|
{
|
|
|
|
|
qDebug("foo: %i", g);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Moo
|
|
|
|
|
{
|
|
|
|
|
};
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Use curly braces when the body of a conditional statement contains more
|
|
|
|
|
than one line, and also if a single line statement is somewhat complex.
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
if (address.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
|
qDebug("%i", i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
if (address.isEmpty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 10; ++i)
|
|
|
|
|
qDebug("%i", i);
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Exception 1: Use braces also if the parent statement covers several
|
|
|
|
|
lines / wraps
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Correct
|
2011-02-04 12:44:43 +01:00
|
|
|
|
if (address.isEmpty()
|
|
|
|
|
|| !isValid()
|
|
|
|
|
|| !codec)
|
2008-12-15 17:48:02 +01:00
|
|
|
|
return false;
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Note: This could be re-written as:
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
// Als correct
|
|
|
|
|
if (address.isEmpty())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!isValid())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (!codec)
|
|
|
|
|
return false;
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
Exception 2: Use braces also in if-then-else blocks where either the
|
|
|
|
|
if-code or the else-code covers several lines
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
if (address.isEmpty())
|
|
|
|
|
--it;
|
|
|
|
|
else {
|
|
|
|
|
qDebug("%s", qPrintable(address));
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
if (address.isEmpty()) {
|
|
|
|
|
--it;
|
|
|
|
|
} else {
|
|
|
|
|
qDebug("%s", qPrintable(address));
|
|
|
|
|
++it;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Wrong
|
|
|
|
|
if (a)
|
|
|
|
|
if (b)
|
|
|
|
|
...
|
|
|
|
|
else
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
if (a) {
|
|
|
|
|
if (b)
|
|
|
|
|
...
|
|
|
|
|
else
|
|
|
|
|
...
|
|
|
|
|
}
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
|
|
|
|
Use curly braces when the body of a conditional statement is empty
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
while (a);
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
while (a) {}
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
|
|
|
|
|
\section2 Parentheses
|
2008-12-15 17:48:02 +01:00
|
|
|
|
Use parentheses to group expressions:
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
if (a && b || c)
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
if ((a && b) || c)
|
|
|
|
|
|
|
|
|
|
// Wrong
|
|
|
|
|
a + b & c
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
(a + b) & c
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-15 17:48:02 +01:00
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
|
|
|
|
|
\section2 Line breaks
|
2008-12-15 17:48:02 +01:00
|
|
|
|
Keep lines shorter than 100 characters; insert line breaks if necessary.
|
2011-02-04 12:44:43 +01:00
|
|
|
|
Commas go at the end of a broken line; operators start at the beginning
|
|
|
|
|
of the new line. The operator is at the end of the line to avoid having
|
|
|
|
|
to scroll if your editor is too narrow.
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\code
|
2008-12-15 17:48:02 +01:00
|
|
|
|
// Wrong
|
|
|
|
|
if (longExpression +
|
|
|
|
|
otherLongExpression +
|
|
|
|
|
otherOtherLongExpression) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Correct
|
|
|
|
|
if (longExpression
|
|
|
|
|
+ otherLongExpression
|
|
|
|
|
+ otherOtherLongExpression) {
|
|
|
|
|
}
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\endcode
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Declarations
|
|
|
|
|
|
|
|
|
|
- Use this order for the access sections of your class: public,
|
|
|
|
|
protected, private. The public section is interesting for every
|
|
|
|
|
user of the class. The private section is only of interest for the
|
|
|
|
|
implementors of the class (you). [Obviously not true since this is
|
|
|
|
|
for developers, and we do not want one developer only to be able to
|
|
|
|
|
read and understand the implementation of class internals. Lgb]
|
|
|
|
|
|
|
|
|
|
- Avoid declaring global objects in the declaration file of the class.
|
|
|
|
|
If the same variable is used for all objects, use a static member.
|
|
|
|
|
|
|
|
|
|
- Avoid global or static variables.
|
|
|
|
|
|
|
|
|
|
|
2008-12-15 17:48:02 +01:00
|
|
|
|
\section2 API/ABI stability
|
|
|
|
|
We currently do not gurantee any API nor ABI compatibility between releases.
|
|
|
|
|
|
|
|
|
|
|
2008-12-11 13:23:03 +01:00
|
|
|
|
\section2 File headers
|
|
|
|
|
|
2010-01-29 21:33:57 +01:00
|
|
|
|
If you create a new file, the top of the file should include a
|
2008-12-11 13:23:03 +01:00
|
|
|
|
header comment equal to the one found in other source files of Qt Creator.
|
|
|
|
|
|
2009-01-21 13:58:04 +01:00
|
|
|
|
\section2 Include order
|
|
|
|
|
|
|
|
|
|
Always go from less general to more general. In a typical implementation
|
|
|
|
|
file that would look like
|
|
|
|
|
\code
|
|
|
|
|
#include "myownheader.h"
|
|
|
|
|
...
|
|
|
|
|
#include "other_headers_from_my_own_plugin.h"
|
|
|
|
|
...
|
|
|
|
|
#include <other_plugin/headers_from_other_plugin.h>
|
|
|
|
|
...
|
|
|
|
|
#include <QtCore/QSomeCoreClass>
|
|
|
|
|
...
|
|
|
|
|
#include <QtGui/QSomeGuiClass>
|
|
|
|
|
...
|
|
|
|
|
#include <some_system_C++_header>
|
|
|
|
|
...
|
|
|
|
|
#include <some_system_C_header>
|
|
|
|
|
\endcode
|
|
|
|
|
This order ensures that the headers are self-contained.
|
|
|
|
|
|
|
|
|
|
Using <...> instead of "..." for headers from other plugins helps
|
|
|
|
|
spotting plugin-external dependencies in the sources.
|
|
|
|
|
|
|
|
|
|
Using empty lines between blocks of "peer" headers are encouraged.
|
|
|
|
|
|
2008-12-11 13:23:03 +01:00
|
|
|
|
\section2 Documentation
|
|
|
|
|
|
|
|
|
|
The documentation is generated from source and header files.
|
|
|
|
|
You document for the other developers, not for yourself.
|
|
|
|
|
In the header you should document interfaces, i.e. what the function does,
|
|
|
|
|
not the implementation.
|
2010-01-29 21:33:57 +01:00
|
|
|
|
In the .cpp files you document the implementation if the implementation
|
2008-12-11 13:23:03 +01:00
|
|
|
|
in non-obvious.
|
|
|
|
|
|
2011-01-05 12:07:24 +01:00
|
|
|
|
\section1 Patterns and practices
|
|
|
|
|
|
|
|
|
|
\section2 Passing file names
|
|
|
|
|
|
|
|
|
|
Qt Creator API expects file names in "portable" format, i.e. with '/'
|
|
|
|
|
instead of '\\' even on Windows. If you want to pass a file name to
|
|
|
|
|
the API that comes from the user, you need to convert it with
|
|
|
|
|
QDir::fromNativeSeparators first. Whenever you present a file name to the user,
|
|
|
|
|
you need to convert it back to native format with QDir::toNativeSeparators.
|
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
When comparing file names consider using FileManager::fixFileName which
|
|
|
|
|
makes sure that paths are clean and absolute and also takes Windows'
|
|
|
|
|
case-insensitivity into account (but is an expensive operation).
|
2011-01-05 12:07:24 +01:00
|
|
|
|
|
|
|
|
|
\section2 Plugin extension points
|
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
A plugin extension point is an interface that is provided by a plugin
|
|
|
|
|
to be implemented by others. The plugin then retrieves all
|
|
|
|
|
implementations of the interface and uses them, they "extend" the
|
|
|
|
|
functionality of the plugin. A common pattern is that the
|
|
|
|
|
implementations of the interface are put into the global object pool
|
|
|
|
|
during plugin initialization, and the plugin retrieves them from the
|
|
|
|
|
object pool at the end of plugin initialization.
|
|
|
|
|
|
|
|
|
|
For example: The Find plugin provides the FindFilter interface for
|
|
|
|
|
others to implement. With the FindFilter interface, additional search
|
|
|
|
|
scopes can be added, that appear in the Advanced Search dialog. The
|
|
|
|
|
Find plugin retrieves all FindFilter implementations (from the global
|
|
|
|
|
object pool, see below) and presents them in the dialog, forwarding the
|
|
|
|
|
actual search request to the correct FindFilter implementation, which
|
|
|
|
|
then performs the search.
|
2011-01-05 12:07:24 +01:00
|
|
|
|
|
|
|
|
|
\section2 Using the global object pool
|
|
|
|
|
|
2011-02-04 12:44:43 +01:00
|
|
|
|
You can add objects to the global object pool via
|
|
|
|
|
\l{ExtensionSystem::PluginManager::addObject()}, and retrieve objects
|
|
|
|
|
of a specific type again via
|
|
|
|
|
\l{ExtensionSystem::PluginManager::getObjects()}. This should mostly
|
|
|
|
|
be used for implementations of \l{Plugin extension points}.
|
2011-01-05 12:07:24 +01:00
|
|
|
|
|
|
|
|
|
Cases where you should not use it are:
|
|
|
|
|
\list
|
2011-02-04 12:44:43 +01:00
|
|
|
|
\o Singletons. Don't put a singleton into the pool, and don't retrieve
|
|
|
|
|
it from there. Use the singleton pattern instead.
|
2011-01-05 12:07:24 +01:00
|
|
|
|
\endlist
|
2008-12-11 13:23:03 +01:00
|
|
|
|
|
2011-02-04 15:16:27 +01:00
|
|
|
|
|
|
|
|
|
\section2 C++ features
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
\o Don’t use exceptions _unless you know what you do_.
|
|
|
|
|
\o Don’t use RTTI (Run-Time Type Information; that is, the typeinfo
|
|
|
|
|
struct, the dynamic_cast or the typeid operators, including throwing
|
|
|
|
|
exceptions) _unless you know what you do_.
|
|
|
|
|
\o Use templates wisely, not just because you can.
|
|
|
|
|
|
|
|
|
|
Hint: Use the compile autotest to see whether a C++ feature is supported
|
|
|
|
|
by all compilers in the test farm.
|
|
|
|
|
|
|
|
|
|
\o All code is ascii only (7-bit characters only, run man ascii if unsure)
|
|
|
|
|
\list
|
|
|
|
|
\o Rationale: We have too many locales inhouse and an unhealthy
|
|
|
|
|
mix of UTF-8 and latin1 systems. Usually, characters > 127 can
|
|
|
|
|
be broken without you even knowing by clicking SAVE in your
|
|
|
|
|
favourite editor.
|
|
|
|
|
\o For strings: Use \nnn (where nnn is the octal representation
|
|
|
|
|
of whatever locale you want your string in) or \xnn (where nn
|
|
|
|
|
is hexadecimal).
|
|
|
|
|
Example: QString s = QString::fromUtf8("\213\005");
|
|
|
|
|
\o For umlauts in documentation, or other non-ASCII characters,
|
|
|
|
|
either use qdoc’s \unicode command or use the relevant macro;
|
|
|
|
|
e.g. \uuml for ü
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
\o Avoid the use of anonymous namespaces in favor of the static keyword
|
|
|
|
|
if possible. A name localized to the compilation unit with static is
|
|
|
|
|
guaranteed to have internal linkage. For names declared in anonymous
|
|
|
|
|
namespaces the C++ standard unfortunately mandates external linkage.
|
|
|
|
|
(7.1.1/6, or see various discussions about this on the gcc mailing
|
|
|
|
|
lists)
|
|
|
|
|
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 QObject usage
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
|
|
|
|
|
\o Every QObject subclass must have a Q_OBJECT macro, even if it
|
|
|
|
|
doesn’t have signals or slots, if it is intended to be used
|
|
|
|
|
with qobject_cast<>.
|
|
|
|
|
|
|
|
|
|
\o Normalize the arguments for signals + slots
|
|
|
|
|
(see QMetaObject::normalizedSignature) inside connect statements
|
|
|
|
|
to safe a few cycles faster signal/slot lookups.
|
|
|
|
|
You can use $QTDIR/util/normalize to normalize existing code.
|
|
|
|
|
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Including headers
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
\o Prefer use this form to include Qt headers:
|
|
|
|
|
\c{#include <QtCore/QWhatEver>}.
|
|
|
|
|
\o Order includes from most-specific to least-specific, i.e.
|
|
|
|
|
\list
|
|
|
|
|
\o \c{#include "myclass.h"}
|
|
|
|
|
\o \c{#include "otherclassinplugin.h"}
|
|
|
|
|
\o \c{#include <otherplugin/someclass.h>"}
|
|
|
|
|
\o \c{#include <QtModule/QtClass>"}
|
|
|
|
|
\o \c{#include <stdthing>"}
|
|
|
|
|
\o \c{#include <system.h>"}
|
|
|
|
|
\endif
|
|
|
|
|
Add empty line between long blocks and try to keep
|
|
|
|
|
alphabetical order within a block.
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
\section2 Casting
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
\o Avoid C casts, prefer C++ casts (static_cast, const_cast,
|
|
|
|
|
reinterpret_cast) Rationale: Both reinterpret_cast and
|
|
|
|
|
C-style casts are dangerous, but at least reinterpret_cast
|
|
|
|
|
won’t remove the const modifier.
|
|
|
|
|
\o Don’t use dynamic_cast, use qobject_cast for QObjects or
|
|
|
|
|
refactor your design, for example by introducing a type()
|
|
|
|
|
method (see QListWidgetItem) _unless you know what you do_.
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section Compiler/Platform specific issues
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
\o Be extremely careful when using the question mark operator.
|
|
|
|
|
If the returned types aren’t identical, some compilers generate
|
|
|
|
|
code that crashes at runtime (you won’t even get a compiler warning).
|
|
|
|
|
\code
|
|
|
|
|
QString s;
|
|
|
|
|
// crash at runtime - QString vs. const char *
|
|
|
|
|
return condition ? s : "nothing";
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
\o Be extremely careful about alignment.
|
|
|
|
|
|
|
|
|
|
Whenever a pointer is cast such that the required alignment of
|
|
|
|
|
the target is increased, the resulting code might crash at runtime
|
|
|
|
|
on some architectures. For example, if a const char * is cast to an
|
|
|
|
|
const int *, it’ll crash on machines where integers have to be
|
|
|
|
|
aligned at a two- or four-byte boundaries.
|
|
|
|
|
|
|
|
|
|
Use a union to force the compiler to align variables correctly.
|
|
|
|
|
In the example below, you can be sure that all instances of
|
|
|
|
|
AlignHelper are aligned at integer-boundaries.
|
|
|
|
|
\code
|
|
|
|
|
union AlignHelper
|
|
|
|
|
{
|
|
|
|
|
char c;
|
|
|
|
|
int i;
|
|
|
|
|
};
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
\o Anything that has a constructor or needs to run code to be
|
|
|
|
|
initialized cannot be used as global object in library code,
|
|
|
|
|
since it is undefined when that constructor/code will be run
|
|
|
|
|
(on first usage, on library load, before main() or not at all).
|
|
|
|
|
|
|
|
|
|
Even if the execution time of the initializer is defined for
|
|
|
|
|
shared libraries, you’ll get into trouble when moving that code
|
|
|
|
|
in a plugin or if the library is compiled statically:
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
// global scope
|
|
|
|
|
// Wrong - default constructor needs to be run to initialize x:
|
|
|
|
|
static const QString x;
|
|
|
|
|
|
|
|
|
|
// Wrong - constructor that takes a const char * has to be run :
|
|
|
|
|
static const QString y = "Hello";
|
|
|
|
|
|
|
|
|
|
// Super wrong:
|
|
|
|
|
QString z;
|
|
|
|
|
|
|
|
|
|
// Wrong, call time of foo() undefined, might not be called at all:
|
|
|
|
|
static const int i = foo();
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
Things you can do:
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
// global scope
|
|
|
|
|
// Works - no constructor must be run, x set at compile time:
|
|
|
|
|
static const char x[] = "someText";
|
|
|
|
|
|
|
|
|
|
// Works - y will be set at compile time:
|
|
|
|
|
static int y = 7;
|
|
|
|
|
|
|
|
|
|
// Works - will be initialized statically, no code being run.
|
|
|
|
|
static MyStruct s = {1, 2, 3};
|
|
|
|
|
|
|
|
|
|
// Pointers to objects are ok, no code needed to be run to
|
|
|
|
|
// initialize ptr:
|
|
|
|
|
static QString *ptr = 0;
|
|
|
|
|
|
|
|
|
|
// Use Q_GLOBAL_STATIC to create static global objects instead:
|
|
|
|
|
|
|
|
|
|
Q_STATIC_GLOBAL(QString, s)
|
|
|
|
|
|
|
|
|
|
void foo()
|
|
|
|
|
{
|
|
|
|
|
s()->append("moo");
|
|
|
|
|
}
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
Note: Static objects in function scope are no problem, the constructor
|
|
|
|
|
will be run the first time the function is
|
|
|
|
|
entered. The code is not reentrant, though.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\o A char is signed or unsigned dependent on the architecture. Use signed
|
|
|
|
|
char or uchar if you explicitely want a signed/unsigned char.
|
|
|
|
|
The following code will break on PPC, for example:
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
char c = 'A';
|
|
|
|
|
// WRONG - condition is always true on platforms where the
|
|
|
|
|
// default is unsigned:
|
|
|
|
|
if (c < 0) { ... }
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
\o Try to avoid 64-bit enum values. The aapcs embedded ABI hard codes
|
|
|
|
|
all enum values to a 32-bit integer.
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Aestethics
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
|
|
|
|
|
\o Prefer enums to define constants over static const int or defines.
|
|
|
|
|
enum values will be replaced by the compiler at compile time,
|
|
|
|
|
resulting in faster code defines are not namespace safe (and look ugly).
|
|
|
|
|
\o Prefer verbose argument names in headers.
|
|
|
|
|
Qt Creator will show the argument names in their completion-box.
|
|
|
|
|
It will look better in the documentation.
|
|
|
|
|
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Things to avoid
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
\o Do not inherit from template/tool classes _unless you know what
|
|
|
|
|
you do_. Possible pitfalls: The destructors are not virtual,
|
|
|
|
|
leading to potential memory leaks. The symbols are not exported
|
|
|
|
|
(and mostly inline), leading to interesting symbol clashes.
|
|
|
|
|
Example: Library A has class Q_EXPORT X: public QList<QVariant> {};
|
|
|
|
|
and library B has class Q_EXPORT Y: public QList<QVariant> {};.
|
|
|
|
|
Suddenly, QList’s symbols are exported from two libraries – /clash/.
|
|
|
|
|
\o Don’t mix const and non-const iterators. This will silently crash
|
|
|
|
|
on broken compilers.
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
// Wrong:
|
|
|
|
|
for (Container::const_iterator it = c.begin(); it != c.end(); ++it)
|
|
|
|
|
// Correct:
|
|
|
|
|
for (Container::const_iterator it = c.constBegin(); it != c.constEnd(); ++it)
|
|
|
|
|
\endcode
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
\section2 Binary and Source Compatibility:
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
\o Definitions:
|
|
|
|
|
\list
|
|
|
|
|
\o Qt 4.0.0 is a major release, Qt 4.1.0 is a minor release,
|
|
|
|
|
Qt 4.1.1 is a patch release.
|
|
|
|
|
\o Backward binary compatibility: Code linked to an earlier
|
|
|
|
|
version of the library keeps working.
|
|
|
|
|
\o Forward binary compatibility: Code linked to a newer
|
|
|
|
|
version of the library works with an older library.
|
|
|
|
|
\o Source code compatibility: Code compiles without modification.
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
\o TRY TO keep backward binary compatibility and backward source code
|
|
|
|
|
compatibility in minor releases.
|
|
|
|
|
NOTE: This is not yet mandatory.
|
|
|
|
|
|
|
|
|
|
\o TRY TO Keep backward and forward binary compatibility and forward
|
|
|
|
|
and backward source code compatibility in patch releases
|
|
|
|
|
\list
|
|
|
|
|
\o Don’t add/remove any public API (e.g. global functions,x
|
|
|
|
|
public/protected/private methods)
|
|
|
|
|
\o Don’t reimplement methods (not even inlines,
|
|
|
|
|
nor protected/private methods)
|
|
|
|
|
\o Check BinaryCompatibilityWorkarounds for ways to keep b/c
|
|
|
|
|
\endlist
|
|
|
|
|
NOTE: This is not yet mandatory!
|
|
|
|
|
|
|
|
|
|
\o Some information on binary compatibility:
|
|
|
|
|
http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++
|
|
|
|
|
|
|
|
|
|
\endlist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Namespacing
|
|
|
|
|
|
|
|
|
|
Read QtInNamespace and keep in mind that all of Qt Creator is
|
|
|
|
|
“namespace aware” code.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\section2 Conventions for public header files
|
|
|
|
|
|
|
|
|
|
Our public header files have to survive the strict settings of
|
|
|
|
|
some of our users. All installed headers have to follow these rules:
|
|
|
|
|
|
|
|
|
|
\list
|
|
|
|
|
|
|
|
|
|
\o No C style casts (-Wold-style-cast). Use static_cast, const_cast
|
|
|
|
|
or reinterpret_cast, for basic types, use the constructor form:
|
|
|
|
|
int(a) instead of (int)a. See chapter “Casting” for more info.
|
|
|
|
|
|
|
|
|
|
\o No float comparisons (-Wfloat-equal). Use qFuzzyCompare to compare
|
|
|
|
|
values with a delta. Use qIsNull to check whether a float is
|
|
|
|
|
binary 0, instead of comparing it to 0.0, or, prefered, move
|
|
|
|
|
such code into an implementaion fole.
|
|
|
|
|
|
|
|
|
|
\o Don’t hide virtual methods in subclasses (-Woverloaded-virtual).
|
|
|
|
|
If the baseclass A has a virtual int val() and subclass B an
|
|
|
|
|
overload with the same name, int val(int x), A’s val function
|
|
|
|
|
is hidden. Use the using keyword to make it visible again, and
|
|
|
|
|
add the following silly workaround for broken compilers:
|
|
|
|
|
\code
|
|
|
|
|
class B: public A
|
|
|
|
|
{
|
|
|
|
|
#ifdef Q_NO_USING_KEYWORD
|
|
|
|
|
inline int val() { return A::val(); }
|
|
|
|
|
#else
|
|
|
|
|
using A::val;
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
\code
|
|
|
|
|
|
|
|
|
|
\o Don’t shadow variables (-Wshadow). Avoid things like this->x = x;
|
|
|
|
|
|
|
|
|
|
\o Don’t give variables the same name as functions declared in
|
|
|
|
|
yours class.
|
|
|
|
|
|
|
|
|
|
\o Always check whether a preprocessor variable is defined before
|
|
|
|
|
probing its value (-Wundef).
|
|
|
|
|
|
|
|
|
|
\code
|
|
|
|
|
// Wrong:
|
|
|
|
|
#if Foo == 0
|
|
|
|
|
|
|
|
|
|
// Correct:
|
|
|
|
|
#if defined(Foo) && Foo == 0
|
|
|
|
|
|
|
|
|
|
// Wrong. We don't want to do "clever" things like that.
|
|
|
|
|
// Use the one above instead, for better readability.
|
|
|
|
|
#if Foo - 0 == 0
|
|
|
|
|
|
|
|
|
|
\endcode
|
|
|
|
|
|
|
|
|
|
\endlist
|
|
|
|
|
|
2008-12-11 13:23:03 +01:00
|
|
|
|
*/
|