For Developers‎ > ‎

Coding Style

Coding style for the Chromium projects generally follows the Google C++ Style Guide (but see below for C++11 note). The notes below are usually just extensions beyond what the Google style guide already says. If this document doesn't mention a rule, follow the Google C++ style. If Google style is flexible on a particular topic, and this document doesn't clarify below, then Chromium style is also flexible on that topic. Objective-C/C++ code should follow the Google Objective-C Style Guide. Java files for Android should use the Java Style Guide. If you use emacs, you may find Google's style definition for c-mode helpful. 

You may also want to refer to common C++ Dos and Don'ts. Now that some of those are compile errors on the clang bots, you may want to read Chromium Style Checker Errors. Cocoa code should be written with the Cocoa Dos and Don'ts in mind.

When working on Blink code, you should use the Blink coding style instead.

Try to follow any per-file conventions you notice when modifying existing code.

The remainder of this page covers rules that are specific to the Chromium projects.

Other languages

C++11

Google style has adopted most C++11 features but Chromium has a more restricted set. The status of C++11 features in Chromium is tracked in the separate C++11 use in Chromium page.

C

C code, such as firmware and other specific codebases in Chromium OS, should follow the Linux kernel Documentation/CodingStyle. Changes to existing C source should maintain consistency with that project's style.

IDL

For IDL files, see Web IDL in Blink: Style.

Jinja

Jinja templates should follow the Jinja Style Guide.

Python

Python code should follow PEP-8, except that Chromium:
  • uses two-space indentation instead of four-space indentation, and
  • uses MixedCase for method names and function names instead of lower_case_with_underscores.
(The rationale for this is mostly legacy reasons: the code was originally written following Google's internal style guideline, the cost of updating all of the code to PEP-8 compliance was not small, and consistency was seen to be a greater virtue than compliance.) depot_tools contains a local copy of pylint, appropriately configured.

Note that asserts are of limited use, and should not be used for validating input – throw an exception instead. Asserts can be used for validating program logic, especially use of interfaces or invariants (e.g., asserting that a function is only called with dictionaries that contain a certain key). See Using Assertions Effectively.

See also the Chromium OS Python Style Guidelines.

Web languages (JavaScript, HTML, CSS)

When working on Web-based UI features, consult the Web Development Style Guide for the Chromium conventions used in JS/CSS/HTML files.

Internal uses of web languages, notably "layout" tests, should preferably follow these style guides, but it is not enforced.

Naming

  • "Chromium" is the name of the project, not the product, and should never appear in code, variable names, API names etc. Use "chrome" instead.
  • Though the Google C++ Style Guide now says to use kConstantNaming for enums, Chromium was written using MACRO_STYLE naming.  Continue to use this style for consistency.
  • Unit tests and performance tests should be placed in the same directory as the functionality they're testing.
  • Functions ending with a ForTesting suffix will be checked at presubmit time to ensure they're only called in a test situation.

Code formatting

  • Put * and & by the type rather than the variable name.
  • Always linebreak after a conditional, even if the body is only a return or other simple action.
  • Wrap after binary operators, not before.  Exception: when you have a log line that is longer than 80 characters, subsequent lines should start with the << operator and should be aligned based on the first << from the original line:

VLOG(1) << "I have a long log message here, with variables like "
        << var1 << " and var2: " << var2;

  • When you derive from a base class, group any overriding functions in your header file in one labeled section.  Use the override specifier on all these functions.
  • For function declarations and definitions, put each argument on a separate line unless the whole declaration fits on one line.
void OK1(TypeA first_argument, TypeB second_argument, TypeC third_argument);
void OK2(TypeA first_argument,
         TypeB second_argument,
         TypeC third_argument);
void OK3ReallyLongFunctionName(
    ReallyLongType really_long_arg,
    ReallyLongType really_long_arg2);

For function calls, it's OK to collapse args onto fewer lines.  Just make sure in either case that all lines of args begin at the same horizontal position.

void OK1(first_argument, second_argument,
         third_argument, fourth_argument);
void OK2ReallyLongFunctionName(
    first_argument, second_argument,
    third_argument, fourth_argument);
  • Prefer (foo == 0) to (0 == foo).
  • Function declaration order should match function definition order.
  • Prefer putting delegate classes in their own header files. Implementors of the delegate interface will often be included elsewhere, which will often cause more coupling with the header of the main class.
  • Don't use else after return:
if (foo)
  return 1;
else
  return 2;

if (foo)
  return 1;
return 2;

return foo ? 1 : 2;

Unnamed Namespaces

  • Items local to a .cc file should be wrapped in an unnamed namespace.  While some such items are already file-scope by default in C++, not all are; also, shared objects on Linux builds export all symbols, so unnamed namespaces (which restrict these symbols to the compilation unit) improve function call cost and reduce the size of entry point tables.

    namespace {

    bool helper() { ... };

    } // namespace

Exporting Symbols

When building shared libraries and DLLs, we need to indicate which functions and classes should be visible outside of the library, and which should only be visible inside the library.
  • Symbols can be exported by annotating with a <COMPONENT>_EXPORT macro name (where <COMPONENT> is the name of the component being built, e.g., BASE, NET, CONTENT, etc.). Function annotations should precede the return type; class annotations should precede the class name:
class FOO_EXPORT Foo {
  void Bar();
  void Baz();
  // ...
};

class FooSingleton {
  FOO_EXPORT Foo& GetFoo();
  FOO_EXPORT Foo& SetFooForTesting(Foo& foo);
  void SetFoo(Foo& foo);
};

This results in Foo::Bar, Foo::Baz, FooSingleton::GetFoo, FooSingleton::SetFooForTesting all being available outside of the DLL, but not FooSingleton::SetFoo.
  • Whether something is exported is distinct from whether it is public or private, or even whether it would normally be considered part of the external API.  For example, if part of the external API is an inlined function that calls a private function, that private function must be exported as well.

Inline functions

  • Simple accessors should generally be the only inline functions. These should be named unix_hacker_style().  Virtual functions should never be declared this way.
  • For more detail, consult the C++ Dos and Don'ts section on inlining.

Logging

  • Remove most logging calls before checking in.  For the rare case when logging needs to stay in the codebase for a while, prefer DVLOG(1) to other logging methods.  This avoids bloating the release executable and in debug can be selectively-enabled at runtime by command-line arguments, like this: ./chrome --v=2 --vmodule=foo=1,*bar/baz*=3.  This will globally print all log levels up through 2, but only through 1 for foo.cc and 3 for any module with the string bar/baz in its full pathname.

Platform-specific code

  • Platform-specific #ifdefs should use the system specific defines in build/build_config.h and not other things such as WIN32.  Code that is specific to Windows or Mac is simple -- just test OS_WIN or OS_MACOSX. But things get subtle from there: ChromiumOS uses the Linux kernel but is different from desktop Linux, and there are also ports to other Unixes (which we don't explicitly support but do make a best-effort attempt to not break).  A summary of the major preprocessor defines:
    • Use OS_POSIX to define something applicable for all non-Windows platforms, including Mac and Linux (for example, pthreads).
    • Use defined(OS_POSIX) && !defined(OS_MACOSX) for POSIX code that is explicitly not OS X, e.g. converting a path from the system native encoding to Unicode.
    • Use TOOLKIT_GTK for GTK code (as used by desktop Linux; e.g. creating/accessing GtkWidget or showing a native file-picker dialog).
    • Use USE_X11 for X11 code (used by desktop Linux/ChromeOS; e.g. dealing with XEvent, to use X extensions). Please do not use OS_LINUX for GTK or X11 code.
    • Use OS_CHROMEOS code specific to ChromiumOS (such as whether to show the wifi status).
    • If you need to do something based on the type of wchar_t, use WCHAR_T_IS_UTF16 or WCHAR_T_IS_UTF32.
  • For platform-specific #includes, put them below the "regular" includes, separated with a blank line.  Repeat the standard header order in the lower section:
#include "base/basictypes.h"
#include "base/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/common/render_messages.h"

#if defined(OS_WIN)
#include <windows.h>
#include "base/foo_win.h"
#elif defined(OS_POSIX)
#include "base/foo_posix.h"
#endif

Types

  • Use size_t for object and allocation sizes, object counts, array and pointer offsets, vector indices, and so on. The signed types are incorrect and unsafe for these purposes. (Integer overflow behavior for signed types is undefined in the C and C++ standards, while the behavior is defined for unsigned types.) The C++ STL is a guide here: they use size_t and foo::size_type for very good reasons.
    • Interfaces (function prototypes) for these uses should use size_t, even if the underlying storage is a smaller unsigned type (e.g. as a space optimization).
  • Be aware that size_t (object sizes and indices), off_t (file offsets), ptrdiff_t (the difference between two pointer values), intptr_t, uint32_t, uint64_t, and so on are not necessarily the same. Use the right type for your purpose.
  • When casting to and from different types, use static_cast<>() when you know the conversion is safe; also consider checked_cast<>() and saturated_cast<>() in base/numerics/safe_conversions.h, which allow you to enforce via CHECK() that the cast did not change the value or to clamp out-of-range values, respectively.
  • Do not use unsigned types to mean "this value should never be < 0". For that, use assertions or run-time checks (as appropriate).
  • In cases where the exact size of the type matters (e.g. a 32-bit pixel value, a bitmask, or a counter that has to be a particular width), use a sized type like uint32_t.  Also, when passing values across network or process boundaries, use explicitly-sized types for safety, since the sending and receiving ends may not have been compiled with the same sizes for things like int and size_t.  However, avoid letting these sized types bleed through the API of the layer in question.
  • Always use size_t directly in preference to std::string::size_type and similar.
  • Don't use std::wstring.  Use string16 or FilePath instead.  (Exception: allowed in Windows-only code where it does not touch a cross-platform API if its use is necessary, e.g. to interact with some Windows API.)

Method signatures

  • After testing, it seems just as fast to return a std::[w]string by value as by out param. So we encourage passing strings out as return values when possible for the sake of readability.

File headers

  • All files in Chromium start with a common license header.  As of May 2013, the header should look like this: 
// Copyright $YEAR The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
      • Note that there's no (c) after the "Copyright".
      • The year should be the current year when a new file is created, and should not be changed when the file is updated thereafter.
      • When adding a new file, don't just copy the header from an existing file, because it may use an outdated style (we don't bother updating old headers).
      • For Chromium OS, replace the "Chromium" by "Chromium OS" or "Chrome OS". Note it's not "ChromiumOS", "ChromeOS", neither "CrOS".
      • The Chromium project hosts mirrors of some upstream open-source projects.  When contributing to these portions of the repository, retain the existing file headers.
      • When writing .h files, use standard include guards (see the Google style guide for naming); do not use #pragma once.  Include guards are portable and seem to be just as efficient even on platforms that do support #pragma once, so there is no reason to use it.

      CHECK(), DCHECK(), and NOTREACHED()

      The CHECK() macro will cause an immediate crash if its condition is not met. DCHECK() is like CHECK() but is only compiled in on debug builds and thus should be preferred over CHECK() for speed and code size reasons. NOTREACHED() is equivalent to DCHECK(false).
      • Use DCHECK() or NOTREACHED() as assertions, e.g. to document pre- and post-conditions. A DCHECK() means "this condition must always be true", not "this condition is normally true, but perhaps not in exceptional cases." Things like disk corruption or strange network errors are examples of exceptional circumstances that nevertheless should NOT result in DCHECK() failure.
      • A consequence of this is that you should not handle DCHECK() failures, even if failure would result in a crash. Attempting to handle a DCHECK() failure is a statement that the DCHECK() can fail, which contradicts the point of writing the DCHECK().  The following kinds of constructs are generally forbidden:
      DCHECK(foo);
      if (!foo) ...  // Can't succeed!

      and

      if (foo) {
        NOTREACHED();
        return;  // Just "DCHECK(foo);" and keep going instead.
      }
      ...
      • Use CHECK() if the consequence of a failed assertion would be a security vulnerability, where crashing the browser is preferable.  Because this takes down the whole browser, sometimes there are better options than CHECK().  For example, if a renderer sends the browser process a malformed IPC, an attacker may control the renderer, but we can simply kill the offending renderer instead of crashing the whole browser.
      • You can also temporarily use CHECK() instead of DCHECK() when trying to force crashes in release builds to sniff out which of your assertions is failing.
      • Don't use these macros in tests, as they crash the test binary and leave bots in a bad state.  Use the ASSERT_xx() and EXPECT_xx() family of macros, which report failures gracefully and can continue running other tests.

      Non-coding miscellany

      • Use UTF-8 file encodings and LF line endings.
      • If you use subversion, configure your ~/.subversion/config (or %APPDATA%\Subversion\config on Windows) file to contain the following properties in /trunk/tools/build/slave/config (ViewVC).