-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Server Code Style
-
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) -
Starting with MongoDB 3.2 code, all code changes must be formatted by Clang-Format 3.6.0 before they are checked in. See clang-format-label for more information.
-
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) 2017 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. */ -
For anything that isn't explicitly covered here, default to the Google C++ Style Guide and the Google JavaScript Style Guide.
Use camelCase for most varNames. Use ProperCase for names of classes and structs. Use camelCase for instances of such classes.
Refer to getting-started-coding-style-guidelines for basic guidelines. Otherwise, default to Google C++ Style Guide for placement of comments.
-
If you must have long inline functions, put them in a -inl.h file.
-
If your inline function is a single line long, put it and its decl on separate lines:
int getLength() const { return _length; } -
If a function is not performance sensitive, and it isn't one line long, put it in the cpp file. Keep code out of headers.
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.
if (0) {
} else if (0) {
} else {
}
do {
} while (0);
class Foo {
private:
int _bar;
};
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.
void foo(int v, MyType myItem) {
}
namespace foo {
// Contents of namespace are not indented.
int foo;
namespace bar {
int bar;
} // namespace bar
} // namespace foo
See Kernel exception architecture <server-exception-architecture>
-
BAD
int foo() { if (x) { ... } } -
GOOD
int foo() { if (!x) return; ... }
Keeps indentation levels down and makes more readable.
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;
To avoid implicit type conversion, use the explicit keyword before constructors that take a single parameter.
-
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"
- 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/thread.hpp>
#include <cstdio>
#include <string>
#include "mongo/db/db.h"
#include "mongo/db/namespace_details.h"
#include "mongo/util/concurrency/qlock.h"
-
#pragma onceat the top, after the licence - Include third party headers first, sorted. blank line.
- Include local headers last, sorted.
- Forward declare, if possible, in lieu of including local headers in headers. Only include things that are directly used in the header itself.
- Do not include platform/basic.h in a header; assume that all source files will include it prior to including the header.
- Disable formatting for template literals
// clang-format off
newCode = `load("${overridesFile}"); (${jsCode})();`;
// clang-format on
- 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 small. This is preferable to inserting your new class into a preexisting file.
- Do not use C-style casts, ever.
- Use
static_cast<>as needed. Useconst_cast<>when no other solutions will work. - Be aware that
dynamic_cast<>, unlike other casts, is done at run-time and calls a function. You should always check the return status ofdynamic_cast<>fornull. -
reinterpret_cast<>should be used sparingly and is typically done for converting structures to raw bytes for use with I/O drivers. - When down-casting from a base type where the program logic guarantees that the runtime type is correct, consider using
checked_cast<>frommongo/base/checked_cast.h. It is equivalent to static_cast in release builds, but adds an invariant to debug builds that ensures the cast is valid.
-
Aspire to embrace RAII (Resource Aquisition Is Initialization)
-
When writing functions that take or return bare pointers, document the ownership semantics in a 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
deleteandfree()are red flags- except in destructors
-
Use smart pointers such as
std::unique_ptrandstd::shared_ptr(know the difference between them!) to avoid memory leaks and ensure allnew's andmalloc's are paired withdelete's andfree's -
Use
ON_BLOCK_EXITorScopeGuardto protect other resources that must be released- e.g.
fopen/fclosepairs - Or, write an object to do this for you via constructor and destructor
- e.g.
In things like serverStatus, include the units in the stat name if there is any chance of ambiguity. For example:
writtenMBtimeMs
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
MBand show in megabytes unless you know it will be tiny. Note you can use a float so0.1MBis 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
Microsas the suffix, e.g.,timeMicros.
As of the 3.2 code, MongoDB uses ESLint version 2.3.0 to lint JS code. ESLint is a JS linting tool that uses the config file located at .eslintrc.yml, in the root of the mongo repository, to control the linting of the JS code.
important
All JS files must be linted by ESLint before they are formatted by clang-format.
Plugins are available for most editors that will automatically run ESLint on file save. It is recommended to use one of these plugins.
Use the Python script buildscripts/eslint.py to check that the JS code is linted correctly as well as to fix linting errors in the code.
To lint JS code:
python buildscripts/eslint.py lint
To auto-fix JS code:
python buildscripts/eslint.py fix
As of the 3.5 code, MongoDB uses Clang-Format version 3.9 to enforce coding style. Clang-Format is a C/C++ & JS code formatting tool that uses the config files located at src/mongo/.clang-format & jstests/.clang-format to control the format of the code.
important
All code changes must be formatted by clang-format before they are checked in.
Plugins are available for most editors that will automatically run clang-format on file save. It is recommended to use one of these plugins.
Use the Python script buildscripts/clang_format.py to check that the C/C++ & JS code is formatted correctly as well as to reformat the code.
To lint code:
python buildscripts/clang_format.py lint
To format code:
python buildscripts/clang_format.py format
Getting started
Building
Testing
- Running Tests
- Writing Tests
- Writing Function-level Benchmarks
- Writing JavaScript Integration-level Performance Tests
- Running Bisect
- Running Minimized Jstestfuzz Tests
- Testing with Antithesis
Testing in Evergreen
Code Style
Server Internals