mfbt/STYLE

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 = mfbt style rules =
     3 == Line length ==
     5 The line limit is 80 characters, except that excessively long blocks of
     6 preprocessor directives may exceed this if it makes the code more readable (e.g.
     7 MOZ_STATIC_ASSERT in Assertions.h.), and unbreakable text in comments (e.g.
     8 URLs) may exceed this as well.  Wrap expressions after binary operators.
    10 == Capitalization ==
    12 Standalone functions, classes, structs, and template parameters are named
    13 InterCaps-style.  Member functions and fields in classes and structs are named
    14 camelCaps-style.
    16 == Indentation ==
    18 Indentation is two spaces, never tabs.
    20   if (x == 2)
    21     return 17;
    23 == Whitespace ==
    25 Surround binary operators with a single space on either side.
    27   if (x == 2)
    28     return 17;
    30 When describing pointer types, the * shall be adjacent to the type name.  (Same
    31 goes for references -- & goes by the type name.)
    33   int
    34   Foo(int* p)
    35   {
    36     typedef void* VoidPtr;
    37     int& i = *p;
    38   }
    40 A corollary: don't mix declaration types by declaring a T and a T* (or a T**,
    41 &c.) in the same declaration.
    43   T* foo, bar; // BAD
    45 == Expressions ==
    47 Ternary expressions (a ? b : c) should use only one line if sufficiently short.
    48 Longer ternary expressions should use multiple lines.  The condition,
    49 consequent, and alternative should each be on separate lines (each part
    50 overflowing to additional lines as necessary), and the ? and : should be aligned
    51 with the start of the condition:
    53   size_t
    54   BinaryTree::height()
    55   {
    56     return isLeaf()
    57            ? 0
    58            : 1 + std::max(left()->height(),
    59                           right()->height());
    60   }
    62 == Bracing ==
    64 Don't brace single statements.
    66   if (y == 7)
    67     return 3;
    68   for (size_t i = 0; i < 5; i++)
    69     frob(i);
    71 But do brace them if the statement (or condition(s) or any additional
    72 consequents, if the braces would be associated with an if statement) occupies
    73 multiple lines.
    75   if (cond1 ||
    76       cond2)
    77   {
    78     action();
    79   }
    80   if (cond1) {
    81     consequent();
    82   } else {
    83     alternative(arg1,
    84                 arg2);
    85   }
    86   if (cond1 || cond2) {
    87     callMethod(arg1,
    88                arg2);
    89   }
    90   for (size_t j = 0;
    91        j < 17;
    92        j++)
    93   {
    94     action();
    95   }
    97 Braces in control flow go at the end of the line except when associated with an
    98 |if| or loop-head where the condition covers multiple lines
   100 == Classes and structs ==
   102 Inside class and structure definitions, public/private consume one level of
   103 indentation.
   105   class Baz
   106   {
   107     public:
   108       Baz() { }
   109   };
   111 The absence of public/private in structs in which all members are public still
   112 consumes a level.
   114   struct Foo
   115   {
   116       int field;
   117   };
   119 Braces delimiting a class or struct go on their own lines.
   121 Member initialization in constructors should be formatted as follows:
   123   class Fnord
   124   {
   125       size_t s1, s2, s3, s4, s5;
   127     public:
   128       Fnord(size_t s) : s1(s), s2(s), s3(s), s4(s), s5(s) { }
   129       Fnord()
   130         : s1(0), /* member initialization can be compressed if desired */
   131           s2(0),
   132           s3(0),
   133           s4(0),
   134           s5(0)
   135       {
   136         ...
   137       }
   138   };
   140 Fields should go first in the class so that the basic structure is all in one
   141 place, consistently.
   143 Use the inline keyword to annotate functions defined inline in a header.  (If
   144 the function is defined inline in the class, don't bother adding it
   145 redundantly.)
   147 Explicitly delete (using Attributes.h's MOZ_DELETE) the copy constructor and
   148 assignment operator from classes not intended to be copied or assigned to avoid
   149 mistakes.
   151   class Funky
   152   {
   153     public:
   154       Funky() { }
   156     private:
   157       Funky(const Funky& other) MOZ_DELETE;
   158       void operator=(const Funky& other) MOZ_DELETE;
   159   };
   161 Include a blank line between sections of structs and classes with different
   162 access control.
   164 The "get" prefix is used when a method is fallible.  If it's infallible, don't
   165 use it.
   167   class String
   168   {
   169     public:
   170       size_t length() const; // not getLength()
   171   };
   173 == Templates ==
   175 Capitalize template parameter names to distinguish them from fields.
   177   template<size_t KeySize, typename T>
   178   class BloomFilter
   179   {
   180   };
   182 Use single-letter names if it makes sense (T for an arbitrary type, K for key
   183 type, V for value type, &c.).  Otherwise use InterCaps-style names.
   185 When declaring or defining a function, template<...> goes on one line, the
   186 return type and other specifiers go on another line, and the function name and
   187 argument list go on a third line.
   189   template<typename T>
   190   inline bool
   191   Vector::add(T t)
   192   {
   193   }
   195 == Namespaces ==
   197 All C++ code shall be in the mozilla namespace, except that functionality only
   198 used to implement external-facing API should be in the mozilla::detail
   199 namespace, indicating that it should not be directly used.
   201 Namespace opening braces go on the same line as the namespace declaration.
   202 Namespace closing braces shall be commented.  Namespace contents are not
   203 indented.
   205   namespace mozilla {
   206   ...
   207   } // namespace mozilla
   209 Don't use |using| in a header unless it's confined to a class or method.
   210 Implementation files for out-of-line functionality may use |using|.
   212 Name data structures and methods which must be usable in C code with a Moz*
   213 prefix, e.g. MozCustomStructure.  If the data structure is not meant to be used
   214 outside of the header in which it is found (i.e. it would be in mozilla::detail
   215 but for its being required to work in C code), add a corresponding comment to
   216 highlight this.
   218 == #includes ==
   220 Headers that include mfbt headers use a fully-qualified include path, even if
   221 full qualification is not strictly necessary.
   223   #include "mozilla/Assertions.h"
   225 mfbt headers should be included first, alphabetically.  Standard includes should
   226 follow, separated from mfbt includes by a blank line.
   228   #include "mozilla/Assertions.h"
   229   #include "mozilla/Attributes.h"
   231   #include <string.h>
   233 If a header dependency is limited simply to the existence of a class,
   234 forward-declare it rather than #include that header.
   236   namespace mozilla {
   238   class BloomFilter;
   239   extern bool
   240   Test(BloomFilter* bf);
   242   } // namespace mozilla
   244 == Preprocessor ==
   246 Include guards should be named by determining the fully-qualified include path,
   247 and substituting _ for / and . in it.  For example, "mozilla/Assertions.h"
   248 becomes mozilla_Assertions_h.
   250 Nested preprocessor directives indent the directive name (but not the #) by two
   251 spaces.
   253   #ifdef __clang__
   254   #  define FOO ...
   255   #else
   256   #  define FOO ...
   257   #endif
   259 Comments within nested preprocessor directives align with directive names at
   260 that nesting depth.
   262   #if defined(__GNUC__)
   263      /* gcc supports C++11 override syntax. */
   264   #  define MOZ_OVERRIDE override
   265   #else
   266   #  define MOZ_OVERRIDE /* unsupported */
   267   #endif
   269 Feature-testing macros may be defined to nothing.  Macros intended to be
   270 textually expanded should be defined to a comment indicating non-support, as
   271 above or as appropriate to the situation.
   273 No particular preference is expressed between testing for a macro being defined
   274 using defined(...) and using #ifdef.
   276 When defining a macro with different expansions for different compilers, the top
   277 level of distinction should be the compiler, and the next nested level should be
   278 the compiler version.  Clang seems likely to be around for awhile, so to reduce
   279 confusion test for it separately from gcc even when it's not strictly necessary.
   281   #if defined(__clang__)
   282   #elif defined(__GNUC__)
   283   #  if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
   284   #  else
   285   #  endif
   286   #elif defined(_MSC_VER)
   287   #endif
   289 But don't distinguish clang's feature support using version checks: use the
   290 __has_feature() and __has_extension() macros instead, because vendors may
   291 customize clang's version numbers.
   293 Use a MOZ_* prefix when defining macros (e.g. MOZ_OVERRIDE, MOZ_LIKELY, and so
   294 on) that are part of the mfbt interface.  (C++ implementation files implementing
   295 mfbt's interface but which are not directly part of that interface may ignore
   296 this rule.)
   298 Prefer inline functions to macros whenever possible.
   300 == Comments ==
   302 Header files shall have a short descriptive comment underneath license
   303 boilerplate indicating what functionality the file implements, to be picked up
   304 by MXR and displayed in directory listings.  (But see bug 717196, which
   305 currently prevents MXR from doing this if the MPL2 boilerplate is used.)
   307   Assertions.h:
   308   ...license boilerplate...
   310   /* Implementations of runtime and static assertion macros for C and C++. */
   312 Classes intended for public use shall have interface comments explaining their
   313 functionality from the user's perspective.  These comments shall include
   314 examples of how the relevant functionality might be used.  These interface
   315 comments use /** */ doxygen/Javadoc-style comments.
   317   /**
   318    * The Frobber class simplifies the process of frobbing.
   319    */
   320   class Frobber
   321   {
   322   };
   324 Comments describing implementation details (tradeoffs considered, assumptions
   325 made, mathematical background, &c.) occur separately from interface comments so
   326 that users need not consider them.  They should go inside the class definition
   327 or inside the appropriate method, depending on the specificity of the comment.
   329 Headers which are intended to be C-compatible shall use only /**/-style
   330 comments.  (Code examples nested inside documentation comments may use //-style
   331 comments.)  Headers which are C++-compatible may also use //-style comments.
   333 Non-interface comments that are /**/-style shall not also be doxygen-style.
   335 Use Python-style ** to denote exponentiation inside comments, not ^ (which can
   336 be confused with C-style bitwise xor).  If you're writing sufficiently complex
   337 math, feel free to descend into LaTeX math mode ;-) inside implementation
   338 comments if you need to.  (But keep it out of interface comments, because most
   339 people probably haven't seen LaTeX.)
   341 == Miscellaneous ==
   343 Enclose C-compatible code in |extern "C"| blocks, and #ifdef __cplusplus the
   344 block start/end as needed.  The contents of these blocks should not be indented.
   346 Add new functionality to new headers unless an existing header makes sense.
   347 Err on the side of more headers rather than fewer, as this helps to minimize
   348 dependencies.
   350 Don't use bool for argument types unless the method is a "set" or "enable"-style
   351 method where the method name and bool value together indicate the sense of its
   352 effect.  Use well-named enums in all other places, so that the semantics of the
   353 argument are clear at a glance and do not require knowing how the method
   354 interprets that argument.
   356   void
   357   setVisible(bool visible); // true clearly means visible, false clearly not
   358   enum Enumerability {
   359     Enumerable,
   360     NonEnumerable
   361   };
   362   bool
   363   DefineProperty(JSObject* obj, const char* name, Value v, Enumerability e);
   365 Use NULL for the null pointer constant.
   367 If a consequent in an if-statement ends with a return, don't specify an else.
   368 The else would be redundant with the return, and not using it avoids excess
   369 indentation.  If you feel the if-else alternation is important as a way to
   370 think about the choice being made, consider a ternary expression instead.
   372   // BAD
   373   if (f())
   374     return 2;
   375   else
   376     return 5;
   377   // GOOD
   378   if (f())
   379     return 2;
   380   return 5;
   381   // GOOD
   382   return f() ? 2 : 5

mercurial