OPTIONS

Server Code Style

Basics

  • Use spaces, no literal tabs.

  • 4 spaces per indentation.

  • Limit lines to 100 columns.

  • Use LF (Unix-style) line endings, not CR-LF (DOS). git has a config option in Windows to convert line endings automatically (core.autocrlf)

  • All new files added to the MongoDB code base should use the following copyright notice and AGPL license language, substituting the current year as appropriate:

     /**
      * Copyright (C) 2014 MongoDB Inc.
      *
      * This program is free software: you can redistribute it and/or  modify
      * it under the terms of the GNU Affero General Public License, version 3,
      * as published by the Free Software Foundation.
      *
      * This program is distributed in the hope that it will be useful,
      * but WITHOUT ANY WARRANTY; without even the implied warranty of
      * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      * GNU Affero General Public License for more details.
      *
      * You should have received a copy of the GNU Affero General Public License
      * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      *
      * As a special exception, the copyright holders give permission to link the
      * code of portions of this program with the OpenSSL library under certain
      * conditions as described in each individual source file and distribute
      * linked combinations including the program with the OpenSSL library. You
      * must comply with the GNU Affero General Public License in all respects
      * for all of the code used other than as permitted herein. If you modify
      * file(s) with this exception, you may extend this exception to your
      * version of the file(s), but you are not obligated to do so. If you do not
      * wish to do so, delete this exception statement from your version. If you
      * delete this exception statement from all source files in the program,
      * then also delete it in the license file.
      */
    
    In some cases the Apache 2.0 license will be substituted for the
    AGPL--if necessary this can be discussed during code review.
    
  • For anything that isn’t explicitly covered here, default to the Google C++ Style Guide and the Google JavaScript Style Guide.

Case

Use camelCase for most varNames. Use ProperCase for names of classes and structs. Use camelCase for instances of such classes.

Comments

Refer to MongoDB Coding Style and General Guidelines for basic guidelines. Otherwise, default to http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Comments for placement of comments.

Inlines

  • Put long inline functions in a -inl.h file.

  • If your inline function is a single line long, put it and its decl on the same line e.g.:

    int length() const { return _length; }
    
  • If a function is not performance sensitive, and it isn’t one (or 2) lines long, put it in the cpp file. Keep code out of headers.

Strings

See util/mongoutils/str.h and bson/stringdata.h

  • Use

    str::startsWith()
    str::endsWith()
    

    and not strstr().

  • Use

    << 'c'
    

    and not << "c".

  • Use

    str[0] == '\0'
    

    and not strlen(str) == 0.

See Server String Manipulation.

Brackets

if (0) {
}
else if (0) {
}
else {
}

do {
} while (0);

Class Members

class Foo {
   int _bar;
};

Functions

Declaration

void foo(int v, MyType myItem);

Avoid declarations of extern functions in source files! Instead, #include a proper .h file. Be sure to match the header filename to the source filename where the function definition appears.

Definition

void foo(int v, MyType myItem) {
}

Invocation

foo(1, MyType());

Templates

set<int> s;

Namespaces

namespace foo {
   int foo;
   namespace bar {
      int bar;
   }
}

Start of File

License (AGPL or Apache, depending on C++ driverness)

Return Early

  • BAD

    int foo() {
       if (x) {
         ...
       }
    }
    
  • GOOD

    int foo() {
       if (!x)
         return;
    
       ...
    }
    

Keeps indentation levels down and makes more readable.

Numeric Constants

Large, round numeric constants should be written in multiplied form so that you never need to count digits.

const int tenMillion = 10*1000*1000;
const int megabyte = 1024*1024;

Explicit Constructors

To avoid implicit type conversion, use the explicit keyword before constructors that take a single parameter.

#includes

  • Use “double quotes” for local code, <angle brackets> for 3rd party or library headers.

    examples:
    #include "mongo/platform/basic.h"
    #include <boost/thread.h>
    #include <vector>
    
  • Always use forward relative path from mongo/src/; do not use ..

    correct:
    #include "mongo/db/namespace_details.h"
    
    incorrect:
    #include "../db/namespace_details.h"
    

For cpp Files

  • Include mongo/platform/basic.h first. blank line.
  • Include your .h file next, if applicable. blank line.
  • Include third party headers next, sorted. blank line.
  • Include local headers last, sorted.
example for classy.cpp:
#include "mongo/platform/basic.h"

#include "mongo/db/classy.h"

#include <boost/thread.h>
#include <stdio.h>
#include <string>

#include "mongo/db/db.h"
#include "mongo/db/namespace_details.h"
#include "mongo/util/concurrency/qlock.h"

For h files

  • #pragma once at the top
  • Forward declare, if possible, in lieu of including local headers in headers. Only include things that are directly used in the header itself.
  • Include third party headers first, sorted. blank line.
  • Include local headers last, sorted.
  • Do not include platform/basic.h in a header; assume that all source files will include it prior to including the header.

File Names

  • Class definitions should go in a header file with the same name as the class. Insert _ in place of a capital letter. Do not use capital letters in filenames! For example:
    • ClassyClass’s definition goes in classy_class.h.
    • ClassyClass’s member function implementations go in classy_class.cpp.
  • Do not be afraid to make another file, even if it is really small. This is preferable to inserting your new class into a preexisting file.

Casting

  • Do not use C-style casts, ever.
  • Use static_cast<> or const_cast<>.
  • Be aware that dynamic_cast<>, unlike other casts, is done at run-time and calls a function. You should always check the return status of dynamic_cast<> for null.
  • reinterpret_cast<> should be used sparingly and is typically done for converting structures to raw bytes for use with I/O drivers.

RAII and Bare vs. Smart Pointers

  • Aspire to embrace RAII

  • When writing functions that take or return bare pointers, document the ownership semantics in the header comment.

    • Is the caller responsible for managing returned pointer’s memory?
    • Does the callee take ownership of the pointed-to parameter, or does the caller retain ownership.

    Prefer caller-retains ownership of parameters and takes ownership of returned pointers, but use the appropriate policy for each situation.

  • Generally, bare calls to delete and free() are red flags

    • except in destructors
  • Use smart pointers such as boost::scoped_ptr and std::auto_ptr (know the difference between them!) to avoid memory leaks and ensure all new‘s and malloc‘s are paired with delete‘s and free‘s

  • Use ON_BLOCK_EXIT or ScopeGuard to protect other resources that must be released

    • e.g. fopen/fclose pairs
    • Or, write an object to do this for you via constructor and destructor

Fields that Include Units

In things like serverStatus, include the units in the stat name if there is any chance of ambiguity. For example:

  • writtenMB
  • timeMs

We should have standards for these – i.e. megabytes should always be MB and not Mb and Megabytes in different places. So the standards are:

  • For bytes: use MB and show in megabytes unless you know it will be tiny. Note you can use a float so 0.1MB is fine to show.
  • For time: use millis (Ms) for time by default. You can also use Secs and a float for times you know will be very long.
  • For microseconds, use Micros as the suffix, e.g., timeMicros.