| = mfbt style rules = |
| |
| == Line length == |
| |
| The line limit is 80 characters, except that excessively long blocks of |
| preprocessor directives may exceed this if it makes the code more readable (e.g. |
| MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g. |
| URLs) may exceed this as well. Wrap expressions after binary operators. |
| |
| == Capitalization == |
| |
| Standalone functions, classes, structs, and template parameters are named |
| InterCaps-style. Member functions and fields in classes and structs are named |
| camelCaps-style. |
| |
| == Indentation == |
| |
| Indentation is two spaces, never tabs. |
| |
| if (x == 2) |
| return 17; |
| |
| == Whitespace == |
| |
| Surround binary operators with a single space on either side. |
| |
| if (x == 2) |
| return 17; |
| |
| When describing pointer types, the * shall be adjacent to the type name. (Same |
| goes for references -- & goes by the type name.) |
| |
| int |
| Foo(int* p) |
| { |
| typedef void* VoidPtr; |
| int& i = *p; |
| } |
| |
| A corollary: don't mix declaration types by declaring a T and a T* (or a T**, |
| &c.) in the same declaration. |
| |
| T* foo, bar; // BAD |
| |
| == Expressions == |
| |
| Ternary expressions (a ? b : c) should use only one line if sufficiently short. |
| Longer ternary expressions should use multiple lines. The condition, |
| consequent, and alternative should each be on separate lines (each part |
| overflowing to additional lines as necessary), and the ? and : should be aligned |
| with the start of the condition: |
| |
| size_t |
| BinaryTree::height() |
| { |
| return isLeaf() |
| ? 0 |
| : 1 + std::max(left()->height(), |
| right()->height()); |
| } |
| |
| == Bracing == |
| |
| Don't brace single statements. |
| |
| if (y == 7) |
| return 3; |
| for (size_t i = 0; i < 5; i++) |
| frob(i); |
| |
| But do brace them if the statement (or condition(s) or any additional |
| consequents, if the braces would be associated with an if statement) occupies |
| multiple lines. |
| |
| if (cond1 || |
| cond2) |
| { |
| action(); |
| } |
| if (cond1) { |
| consequent(); |
| } else { |
| alternative(arg1, |
| arg2); |
| } |
| if (cond1 || cond2) { |
| callMethod(arg1, |
| arg2); |
| } |
| for (size_t j = 0; |
| j < 17; |
| j++) |
| { |
| action(); |
| } |
| |
| Braces in control flow go at the end of the line except when associated with an |
| |if| or loop-head where the condition covers multiple lines |
| |
| == Classes and structs == |
| |
| Inside class and structure definitions, public/private consume one level of |
| indentation. |
| |
| class Baz |
| { |
| public: |
| Baz() { } |
| }; |
| |
| The absence of public/private in structs in which all members are public still |
| consumes a level. |
| |
| struct Foo |
| { |
| int field; |
| }; |
| |
| Braces delimiting a class or struct go on their own lines. |
| |
| Member initialization in constructors should be formatted as follows: |
| |
| class Fnord |
| { |
| size_t s1, s2, s3, s4, s5; |
| |
| public: |
| Fnord(size_t s) : s1(s), s2(s), s3(s), s4(s), s5(s) { } |
| Fnord() |
| : s1(0), /* member initialization can be compressed if desired */ |
| s2(0), |
| s3(0), |
| s4(0), |
| s5(0) |
| { |
| ... |
| } |
| }; |
| |
| Fields should go first in the class so that the basic structure is all in one |
| place, consistently. |
| |
| Use the inline keyword to annotate functions defined inline in a header. (If |
| the function is defined inline in the class, don't bother adding it |
| redundantly.) |
| |
| Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and |
| assignment operator from classes not intended to be copied or assigned to avoid |
| mistakes. |
| |
| class Funky |
| { |
| public: |
| Funky() { } |
| |
| private: |
| Funky(const Funky& other) MOZ_DELETE; |
| void operator=(const Funky& other) MOZ_DELETE; |
| }; |
| |
| Include a blank line between sections of structs and classes with different |
| access control. |
| |
| The "get" prefix is used when a method is fallible. If it's infallible, don't |
| use it. |
| |
| class String |
| { |
| public: |
| size_t length() const; // not getLength() |
| }; |
| |
| == Templates == |
| |
| Capitalize template parameter names to distinguish them from fields. |
| |
| template<size_t KeySize, typename T> |
| class BloomFilter |
| { |
| }; |
| |
| Use single-letter names if it makes sense (T for an arbitrary type, K for key |
| type, V for value type, &c.). Otherwise use InterCaps-style names. |
| |
| When declaring or defining a function, template<...> goes on one line, the |
| return type and other specifiers go on another line, and the function name and |
| argument list go on a third line. |
| |
| template<typename T> |
| inline bool |
| Vector::add(T t) |
| { |
| } |
| |
| == Namespaces == |
| |
| All C++ code shall be in the mozilla namespace, except that functionality only |
| used to implement external-facing API should be in the mozilla::detail |
| namespace, indicating that it should not be directly used. |
| |
| Namespace opening braces go on the same line as the namespace declaration. |
| Namespace closing braces shall be commented. Namespace contents are not |
| indented. |
| |
| namespace mozilla { |
| ... |
| } // namespace mozilla |
| |
| Don't use |using| in a header unless it's confined to a class or method. |
| Implementation files for out-of-line functionality may use |using|. |
| |
| Name data structures and methods which must be usable in C code with a Moz* |
| prefix, e.g. MozCustomStructure. If the data structure is not meant to be used |
| outside of the header in which it is found (i.e. it would be in mozilla::detail |
| but for its being required to work in C code), add a corresponding comment to |
| highlight this. |
| |
| == #includes == |
| |
| Headers that include mfbt headers use a fully-qualified include path, even if |
| full qualification is not strictly necessary. |
| |
| #include "mozilla/Assertions.h" |
| |
| mfbt headers should be included first, alphabetically. Standard includes should |
| follow, separated from mfbt includes by a blank line. |
| |
| #include "mozilla/Assertions.h" |
| #include "mozilla/Attributes.h" |
| |
| #include <string.h> |
| |
| If a header dependency is limited simply to the existence of a class, |
| forward-declare it rather than #include that header. |
| |
| namespace mozilla { |
| |
| class BloomFilter; |
| extern bool |
| Test(BloomFilter* bf); |
| |
| } // namespace mozilla |
| |
| == Preprocessor == |
| |
| Include guards should be named by determining the fully-qualified include path, |
| then substituting _ for / and . in it, and finally appending a trailing _. For |
| example, "mozilla/Assertions.h" becomes mozilla_Assertions_h_. |
| |
| Nested preprocessor directives indent the directive name (but not the #) by two |
| spaces. |
| |
| #ifdef __clang__ |
| # define FOO ... |
| #else |
| # define FOO ... |
| #endif |
| |
| Comments within nested preprocessor directives align with directive names at |
| that nesting depth. |
| |
| #if defined(__GNUC__) |
| /* gcc supports C++11 override syntax. */ |
| # define MOZ_OVERRIDE override |
| #else |
| # define MOZ_OVERRIDE /* unsupported */ |
| #endif |
| |
| Feature-testing macros may be defined to nothing. Macros intended to be |
| textually expanded should be defined to a comment indicating non-support, as |
| above or as appropriate to the situation. |
| |
| No particular preference is expressed between testing for a macro being defined |
| using defined(...) and using #ifdef. |
| |
| When defining a macro with different expansions for different compilers, the top |
| level of distinction should be the compiler, and the next nested level should be |
| the compiler version. Clang seems likely to be around for awhile, so to reduce |
| confusion test for it separately from gcc even when it's not strictly necessary. |
| |
| #if defined(__clang__) |
| #elif defined(__GNUC__) |
| # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) |
| # else |
| # endif |
| #elif defined(_MSC_VER) |
| #endif |
| |
| But don't distinguish clang's feature support using version checks: use the |
| __has_feature() and __has_extension() macros instead, because vendors may |
| customize clang's version numbers. |
| |
| Use a MOZ_* prefix when defining macros (e.g. MOZ_OVERRIDE, MOZ_LIKELY, and so |
| on) that are part of the mfbt interface. (C++ implementation files implementing |
| mfbt's interface but which are not directly part of that interface may ignore |
| this rule.) |
| |
| Prefer inline functions to macros whenever possible. |
| |
| == Comments == |
| |
| Header files shall have a short descriptive comment underneath license |
| boilerplate indicating what functionality the file implements, to be picked up |
| by MXR and displayed in directory listings. (But see bug 717196, which |
| currently prevents MXR from doing this if the MPL2 boilerplate is used.) |
| |
| Assertions.h: |
| ...license boilerplate... |
| |
| /* Implementations of runtime and static assertion macros for C and C++. */ |
| |
| Classes intended for public use shall have interface comments explaining their |
| functionality from the user's perspective. These comments shall include |
| examples of how the relevant functionality might be used. These interface |
| comments use /** */ doxygen/Javadoc-style comments. |
| |
| /** |
| * The Frobber class simplifies the process of frobbing. |
| */ |
| class Frobber |
| { |
| }; |
| |
| Comments describing implementation details (tradeoffs considered, assumptions |
| made, mathematical background, &c.) occur separately from interface comments so |
| that users need not consider them. They should go inside the class definition |
| or inside the appropriate method, depending on the specificity of the comment. |
| |
| Headers which are intended to be C-compatible shall use only /**/-style |
| comments. (Code examples nested inside documentation comments may use //-style |
| comments.) Headers which are C++-compatible may also use //-style comments. |
| |
| Non-interface comments that are /**/-style shall not also be doxygen-style. |
| |
| Use Python-style ** to denote exponentiation inside comments, not ^ (which can |
| be confused with C-style bitwise xor). If you're writing sufficiently complex |
| math, feel free to descend into LaTeX math mode ;-) inside implementation |
| comments if you need to. (But keep it out of interface comments, because most |
| people probably haven't seen LaTeX.) |
| |
| == Miscellaneous == |
| |
| Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the |
| block start/end as needed. The contents of these blocks should not be indented. |
| |
| Add new functionality to new headers unless an existing header makes sense. |
| Err on the side of more headers rather than fewer, as this helps to minimize |
| dependencies. Don't add anything to Util.h, which will be split into multiple |
| headers at some point (bug 713082). |
| |
| Don't use bool for argument types unless the method is a "set" or "enable"-style |
| method where the method name and bool value together indicate the sense of its |
| effect. Use well-named enums in all other places, so that the semantics of the |
| argument are clear at a glance and do not require knowing how the method |
| interprets that argument. |
| |
| void |
| setVisible(bool visible); // true clearly means visible, false clearly not |
| enum Enumerability { |
| Enumerable, |
| NonEnumerable |
| }; |
| bool |
| DefineProperty(JSObject* obj, const char* name, Value v, Enumerability e); |
| |
| Use NULL for the null pointer constant. |
| |
| If a consequent in an if-statement ends with a return, don't specify an else. |
| The else would be redundant with the return, and not using it avoids excess |
| indentation. If you feel the if-else alternation is important as a way to |
| think about the choice being made, consider a ternary expression instead. |
| |
| // BAD |
| if (f()) |
| return 2; |
| else |
| return 5; |
| // GOOD |
| if (f()) |
| return 2; |
| return 5; |
| // GOOD |
| return f() ? 2 : 5 |