Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
en:doc:convention_de_codage [07/04/2013 19:34] – [Switch statements] typo xavier | en:doc:convention_de_codage [20/11/2014 14:01] (current) – external edit 127.0.0.1 | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== QET Coding style ====== | ||
+ | |||
+ | Inspired from http:// | ||
+ | |||
+ | This is an overview of the coding conventions to be used when writing code for the QElectroTech project. | ||
+ | |||
+ | ===== Indentation and alignment ===== | ||
+ | |||
+ | * real tabs for indentation, | ||
+ | * one real tab is one 0x09 ASCII character, not a bunch of 0x20 spaces. | ||
+ | * It is strongly recommended to work with an editor that highlights differences between spaces and tabs to avoid shame and mockery. | ||
+ | * Use one tab character to mark each semantic depth increment. | ||
+ | * Indentation = tabs: never use spaces at the beginning of a line | ||
+ | * Do not ask how long a tab should be: configure your editor so it fits your taste | ||
+ | * You may also use tabs within long conditions or to make long function calls more readable: <code cpp> | ||
+ | void Class:: | ||
+ | int dummy_return_value = -1; | ||
+ | if ( | ||
+ | string.length() < 567 && | ||
+ | !suffix.isEmpty() // forget the dummy code, notice the indentation | ||
+ | ) { | ||
+ | dummy_return_value = string.lastIndexOf( | ||
+ | QRegExp(" | ||
+ | 42 | ||
+ | ); | ||
+ | } | ||
+ | return(dummy_return_value); | ||
+ | }</ | ||
+ | * Alignment = spaces: Never use tabs anywhere else than at the beginning of a line | ||
+ | * You may use spaces to align e.g. similar function arguments; for instance: <code cpp> | ||
+ | object -> method(arg1, | ||
+ | object -> method(argument1, | ||
+ | </ | ||
+ | |||
+ | ===== Encoding ===== | ||
+ | Regarding indentation, | ||
+ | |||
+ | ===== End of lines ===== | ||
+ | Unix-style only, Unix-style everywhere: lines should be separated with a LF (Line Feed, the Unix way) character, not a CR (Carriage Return, the Mac way) nor a CRLF (the Windows way). The last line of a file should also end with a LF. | ||
+ | |||
+ | ===== Declaring variables ===== | ||
+ | |||
+ | * You may declare several variables on the same line, especially if their use or meaning are related. | ||
+ | * Avoid short or meaningless names (e.g. " | ||
+ | * Single character variable names are only okay for counters and temporaries, | ||
+ | * Wait when declaring a variable until it is needed, unless you think it really deserves, for clarity reasons, to be declared next to another specific one. | ||
+ | * variables have no uppercase characters at all and feature underscores to achieve readability, | ||
+ | * private and protected attributes should end with an underscore, e.g. font_size_ | ||
+ | * While this underscore habit is remotely inspired from the hungarian notation, the QElectroTech project does not use it at all. So avoid suffixes and modifiers such as m_ / g_ / s_ / l_ ... | ||
+ | * rules for public attributes are rather undefined because their usage is discouraged. | ||
+ | * avoid abbreviations: | ||
+ | // Wrong | ||
+ | short Cntr; | ||
+ | char ITEM_DELIM = ' | ||
+ | int ConductorsCount; | ||
+ | |||
+ | // Correct | ||
+ | short counter; | ||
+ | char item_delimiter = ' | ||
+ | int conductors_count; | ||
+ | </ | ||
+ | * classes always start with an upper-case letter. Classes that have no luck to be reused in a common library start with ' | ||
+ | * Abbreviations are NOT camel-cased (e.g. QETApp) | ||
+ | |||
+ | ===== Whitespace ===== | ||
+ | |||
+ | * Use blank lines to group statements together where suited | ||
+ | * Always use only one blank line | ||
+ | * Never use spaces right after an opening parenthese or before a closing one: if (condition), | ||
+ | * Never let spaces at the end of a line. | ||
+ | * Always use a single space between < | ||
+ | * Always use a single space after a keyword and before a curly brace: <code cpp> | ||
+ | // Wrong | ||
+ | if ( foo ) { | ||
+ | } | ||
+ | // Wrong | ||
+ | if(foo){ | ||
+ | } | ||
+ | |||
+ | // Correct | ||
+ | if (foo) { | ||
+ | } | ||
+ | </ | ||
+ | * For pointers or references, always use a single space between the type and ‘*’ or ‘& | ||
+ | char *x; | ||
+ | const QString & | ||
+ | const char * const y = " | ||
+ | </ | ||
+ | * Surround binary operators with spaces. | ||
+ | * Especially, surround the -> operator with spaces: <code cpp> | ||
+ | my_object -> interestingMethod(); | ||
+ | </ | ||
+ | * No space after a cast. | ||
+ | * Avoid C-style casts when possible: C++ provide static_cast, | ||
+ | // Wrong | ||
+ | char* blockOfMemory = (char* ) malloc(data.size()); | ||
+ | |||
+ | // Correct | ||
+ | char *block_of_memory = reinterpret_cast< | ||
+ | </ | ||
+ | |||
+ | ===== Braces ===== | ||
+ | |||
+ | * As a base rule, the left curly brace goes on the same line as the start of the statement: <code cpp> | ||
+ | // Wrong | ||
+ | if (codec) | ||
+ | { | ||
+ | } | ||
+ | |||
+ | // Correct | ||
+ | if (codec) { | ||
+ | } | ||
+ | </ | ||
+ | * Exception: constructors with attribute initialization statements: <code cpp> | ||
+ | VeryInterestingClass:: | ||
+ | simple_attribute(42), | ||
+ | complicated_attribute(43) | ||
+ | { | ||
+ | // more complex code | ||
+ | } | ||
+ | </ | ||
+ | * Conditions: either the condition is simple enough to fit on a single line, or you must use braces: <code cpp> | ||
+ | // Correct: simple conditions that fit on a single line are ok | ||
+ | if (things -> areNotLikeExpected()) return; | ||
+ | |||
+ | // Correct: otherwise, use braces | ||
+ | if (things -> areNotLikeExpected()) { | ||
+ | // you can even use them when there is only one statement... future | ||
+ | // modifications will result in commit diff which are easier to review | ||
+ | doSomeStuff(foo, | ||
+ | doSomethingElse(bar, | ||
+ | } | ||
+ | else { | ||
+ | // another tip: "} else {" statements are allowed, but splitting the else | ||
+ | // part this way make it easier to comment and/or remove | ||
+ | beginUsualStuff(foo, | ||
+ | beginUsualStuff(foo, | ||
+ | beginUsualStuff(foo, | ||
+ | } | ||
+ | |||
+ | // Wrong: two lines, no braces | ||
+ | if (my && shiny && condition || evaluates ^ to_true) | ||
+ | return -1; | ||
+ | |||
+ | // In case of doubt: use braces. | ||
+ | </ | ||
+ | |||
+ | ===== Line breaks ===== | ||
+ | |||
+ | * What does "fit on a single line" mean? The QElectroTech project does not enforce the good old 80 characters limitation (thus avoiding questions such as "How many chars/ | ||
+ | |||
+ | ===== Parentheses ===== | ||
+ | |||
+ | * Use parentheses to group expressions in order to avoid ambiguous writings: when reading your code, nobody should ever have to think "f*ck, what are the precedence rules again?": | ||
+ | // Wrong | ||
+ | if (a && b || c) | ||
+ | |||
+ | // Correct | ||
+ | if ((a && b) || c) | ||
+ | |||
+ | // Wrong | ||
+ | a + b & c | ||
+ | |||
+ | // Correct | ||
+ | (a + b) & c | ||
+ | </ | ||
+ | |||
+ | ===== Switch statements ===== | ||
+ | |||
+ | * oh, yeah, switch statements. Well. Err. How to say. Surely there are switch statements in QElectroTech... like, 24 of them in the whole code. Clearly, we tend to prefer if statements, which are easier to read and less error-prone. | ||
+ | |||
+ | ===== Declaring methods ===== | ||
+ | * Methods are of course declared in .h files, and most often implemented in .cpp files; | ||
+ | * getters/ | ||
+ | * Methods begin with a lowercase character, never feature any underscore and are camel-cased, | ||
+ | * We do not duplicate Doxygen documentation: | ||
+ | * Doxygen documentation should go in the header for abstract methods (i.e. "this method is abstract and shall be reimplemented to do this and that") | ||
+ | * Doxygen documentation should go above the implementation for regular methods | ||
+ | * Doxygen comments are started with %%/**%% and ended with %%*/%% | ||
+ | * intermediate lines do not feature extra * (did you know? they are optional) | ||
+ | * intermediate lines are typically indented with tabs | ||
+ | * once this semantic indentation is applied, you can switch to spaces e.g. to please Doxygen list parser: | ||
+ | |||
+ | <code cpp> | ||
+ | /** | ||
+ | Represents the kind of a particular conductor: | ||
+ | * Simple: no symbols, no text input | ||
+ | * Single: singleline symbols, no text input | ||
+ | * Multi: text input, no symbol | ||
+ | */ | ||
+ | enum ConductorType { Simple, Single, Multi }; | ||
+ | </ | ||
+ | |||
+ | ===== What to commit ===== | ||
+ | * Each commit should represent either a complete feature or an atomic modification that will lead to that feature | ||
+ | * The trunk will of course end regularly broken -- this does not justify committing very bad code | ||
+ | * Do not commit commented out code (aka " | ||
+ | * Do not commit your name or trigram in a comment -- VCS solutions track the author of each line (e.g. svn annotate) | ||
+ | * Your commit should have a short, meaningful commit message: use English, remain formal (i.e. avoid things like " | ||
+ | |||
+ | TODO Describe conventions to follow when declaring a class. |