diff options
author | hjk <qtc-committer@nokia.com> | 2011-02-04 15:16:27 +0100 |
---|---|---|
committer | hjk <qtc-committer@nokia.com> | 2011-02-04 15:16:55 +0100 |
commit | 8a2aab79e9db6a6bf0c179e8e84a812d0c1b62c1 (patch) | |
tree | 4c83b16990e41764167de8b6194afa0181e177af /doc/api/coding-style.qdoc | |
parent | 58ca05efcd9e0cdd2bb7ea0db0aef445a773979c (diff) | |
download | qt-creator-8a2aab79e9db6a6bf0c179e8e84a812d0c1b62c1.tar.gz |
coding style: incorporate some of the Qt guide lines
Diffstat (limited to 'doc/api/coding-style.qdoc')
-rw-r--r-- | doc/api/coding-style.qdoc | 429 |
1 files changed, 368 insertions, 61 deletions
diff --git a/doc/api/coding-style.qdoc b/doc/api/coding-style.qdoc index e89f1f9cee..832b21cbbd 100644 --- a/doc/api/coding-style.qdoc +++ b/doc/api/coding-style.qdoc @@ -75,8 +75,7 @@ See http://qt.gitorious.org/qt/pages/QtContributionGuidelines We have several guidelines on code constructs, some of these exist to make the code faster, others to make the code clearer. Yet others -exist to allow us to take advantage of the strong type checking -in C++. +exist to allow us to take advantage of the strong type checking in C++. \list 1 \o Declaration of variables should wait as long as possible. The rule @@ -147,28 +146,36 @@ in C++. \section1 Formatting -\section2 Declarations +\section2 Naming rules -Only one declaration on each line. -\code - int a; - int b; - -NOT- - int a, b; // not used in Qt Creator -\endcode + \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 - This is especially important when initialization is done at the same - time. -\code - QString a = "Joe"; - QString b = "Foo"; - -NOT- - QString a = "Joe", b = "Foo"; // not used in Qt Creator -\endcode + +\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 [Note that 'QString a = "Joe"' is formally calling a copy constructor on a temporary constructed from a string literal and therefore has the potential of being more expensive then direct construction by - 'QString a("joe")'. However the compiler is allowed to elide the copy + 'QString a("Joe")'. However the compiler is allowed to elide the copy (even if it had side effects), and modern compilers typically do so. Given these equal costs, Qt Creator code favours the '=' idiom as it is in @@ -176,6 +183,23 @@ Only one declaration on each line. mistaken as function declaration, _and_ reduces the level of nested parantheses in more initializations.] + \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 + + \section2 Pointers and references @@ -187,8 +211,6 @@ Only one declaration on each line. char & c = *p; // not used in Qt Creator \endcode - This is simply in line with the official Qt guide lines. - Also note that we will have: \code const char *p; @@ -232,48 +254,12 @@ Only one declaration on each line. -\section2 Naming rules - - Simply follow the style of Qt proper. As examples: - \list - \o Use descriptive but simple and short names. Do not abbreviate. - - \o Class names are capitalized, and function names lowercased. - Enums are named like Classes, values are in lower-case. - \endlist - - - -\section2 Formatting - We are using the Qt Coding style, please follow the guidelines below. - -Indentation +\section2 Indentation Four spaces, no tabs. -Declaring variables - \list - \o Declare each variable on a separate line. - \o Avoid short (e.g., a, rbarr, nughdeget) names whenever possible. - \o Single character variable names are only okay for counters and - temporaries, where the purpose of the variable is obvious. - \o Wait with declaring a variable until it is needed. - \o Variables and functions start with a small letter. - \o Each consecutive word in a variable's name starts with a capital letter. - - \o Avoid abbreviations - // Wrong - int a, b; - char *c, *d; - // Correct - int height; - int width; - char *nameOfThis; - char *nameOfThat; - \endlist - -Whitespace +\section2 Whitespace \list \o Use blank lines to group statements together where suited. \o Always use only one blank line. @@ -419,7 +405,8 @@ Braces while (a) {} \endcode -Parentheses + +\section2 Parentheses Use parentheses to group expressions: \code // Wrong @@ -435,7 +422,8 @@ Parentheses (a + b) & c \endcode -Line breaks + +\section2 Line breaks Keep lines shorter than 100 characters; insert line breaks if necessary. 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 @@ -560,4 +548,323 @@ Cases where you should not use it are: it from there. Use the singleton pattern instead. \endlist + +\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 + */ |