Coding style

이 문서는 모질라 코드베이스에서 사용되는 기본 스타일과 패턴을 설명합니다. 새로운 코드는 이러한 표준을 준수해야하므로 기존 코드와 마찬가지로 유지 관리가 쉽습니다. 예외가 있지만 규칙을 아는 것은 아주 중요합니다!



특히 이 문서는 Mozilla 코드베이스에 익숙하지 않은 사람들을 위하여 작성되었고 코드 검토 과정를 위해 사용할 수 있습니다. 검토를 요청하기 전에 코드가 권장 사항을 준수하는지 이 문서를 읽으면서 확인하세요.

Article navigation

  1. Naming_and_formatting_code.
  2. General practices.
  3. C/C++ practices.
  4. JavaScript practices.
  5. Java practices.
  6. Makefile/ practices.
  7. Python practices.
  8. SVG practices.
  9. COM, pointers and strings.
  10. IDL.
  11. Error handling.
  12. C++ strings.
  13. Usage of PR_(MAX|MIN|ABS|ROUNDUP) macro calls

Naming and formatting code

The following norms should be followed for new code. For existing code, use the prevailing style in a file or module, ask the owner if you are in another team's codebase or it's not clear what style to use.


No tabs. No whitespace at the end of a line.

Unix-style linebreaks ('\n'), not Windows-style ('\r\n').

Line length

80 characters or less (for laptop side-by-side diffing and two-window tiling; also for Bonsai / hgweb and hardcopy printing).


Two spaces per logic level, or four spaces in Python code.

Note that class visibility and goto labels do not consume a logic level, but switch case labels do. See examples below.

Control structures

Use K&R bracing style: left brace at end of first line, 'cuddled' else on both sides.

Note: Class and function definitions are not control structures; left brace goes by itself on the second line and without extra indentation, generally in C++.

Always brace controlled statements, even a single-line consequent of if else else. This is redundant, typically, but it avoids dangling else bugs, so it's safer at scale than fine-tuning.


if (...) {
} else if (...) {
} else {

while (...) {

do {
} while (...);

for (...; ...; ...) {

switch (...) {
  case 1: {
    // When you need to declare a variable in a switch, put the block in braces.
    int var;
  case 2:

You can achieve the following switch statement indentation in emacs by setting the "case-label" offset:

(c-set-offset 'case-label '+)

Control keywords if, for, while, and switch are always followed by a space to distinguish them from function calls, which have no trailing space.
else should only ever be followed by { or if; i.e., other control keywords are not allowed and should be placed inside braces.

C++ namespaces

Mozilla project C++ declarations should be in the "mozilla" namespace.  Modules should avoid adding nested namespaces under "mozilla", unless they are meant to contain names which have a high probability of colliding with other names in the code base. For example, Point, Path, etc.   Such symbols can be put under module-specific namespaces, under "mozilla", with short all-lowercase names.  Other global namespaces besides "mozilla" are not allowed.

No "using" statements are allowed in header files, except inside class definitions or functions. (We don't want to pollute the global scope of compilation units that use the header file.)

using namespace ...; is only allowed in .cpp files after all #includes. Prefer to wrap code in namespace ... { ... }; instead. if possible.  using namespace ...; should always specify the fully qualified namespace.  That is, to use Foo::Bar do not write using namespace Foo; using namespace Bar;, write using namespace Foo::Bar;

Don't indent code inside namespace ... { ... }.  You can prevent this, inside emacs, by setting the "innamespace" offset:

(c-set-offset 'innamespace 0)

Anonymous namespaces

We prefer using "static", instead of anonymous C++ namespaces. This may change once there is better debugger support (especially on Windows) for placing breakpoints, etc. on code in anonymous namespaces. You may still use anonymous namespaces for things that can't be hidden with 'static', such as types, or certain objects which need to be passed to template functions.

C++ classes 

namespace mozilla {

class MyClass : public A

class MyClass
  : public X  // When deriving from more than one class, put each on its own line.
  , public Y
  MyClass(int aVar, int aVar2)
    : mVar(aVar)
    , mVar2(aVar2)

  // Tiny constructors and destructors can be written on a single line.
  MyClass() { ... }

  // Special member functions, like constructors, that have default bodies
  // should use '= default' annotation instead.
  MyClass() = default;

  // Unless it's a copy or move constructor or you have a specific reason to allow
  // implicit conversions, mark all single-argument constructors explicit.
  explicit MyClass(OtherClass aArg)

  // This constructor can also take a single argument, so it also needs to be marked
  // explicit.
  explicit MyClass(OtherClass aArg, AnotherClass aArg2 = AnotherClass())

  int TinyFunction() { return mVar; }  // Tiny functions can be written in a single line.

  int LargerFunction()

  int mVar;

} // namespace mozilla

Define classes using the style given above.

Existing classes in the global namespace are named with a short prefix (For example, "ns") as a pseudo-namespace.

For small functions, constructors, or other braced constructs, it's okay to collapse the definition to one line, as shown for TinyFunction above. For larger ones, use something similar to method declarations, below.

Methods and functions


In C/C++, method names should be capitalized and use camelCase.  Typenames, and the names of arguments, should be separated with a single space character.

template<typename T>  // Templates on own line.
static int            // Return type on own line for top-level functions.
MyFunction(const nsACstring& aStr,
           mozilla::UniquePtr<const char*>&& aBuffer,
           nsISupports* aOptionalThing = nullptr)

MyClass::Method(const nsACstring& aStr,
                mozilla::UniquePtr<const char*>&& aBuffer,
                nsISupports* aOptionalThing = nullptr)

Getters that never fail, and never return null, are named Foo(), while all other getters use GetFoo(). Getters can return an object value, via a Foo** aResult outparam (typical for an XPCOM getter), or as an already_AddRefed<Foo> (typical for a WebIDL getter, possibly with an ErrorResult& rv parameter), or occasionally as a Foo* (typical for an internal getter for an object with a known lifetime). See bug 223255 for more information.

XPCOM getters always return primitive values via an outparam, while other getters normally use a return value.

Method declarations must use, at most, one of the following keywords: virtual, override, or final.  Use virtual to declare virtual methods, which do not override a base class method with the same signature.  Use override to declare virtual methods which do override a base class method, with the same signature, but can be further overridden in derived classes.  Use final to declare virtual methods which do override a base class method, with the same signature, but can NOT be further overridden in the derived classes.  This should help the person reading the code fully understand what the declaration is doing, without needing to further examine base classes.


In JavaScript, functions should use camelCase, but should not capitalize the first letter. Methods should not use the named function expression syntax, because our tools understand method names:

doSomething: function (aFoo, aBar) {

In-line functions should have spaces around braces, except before commas or semicolons:

function valueObject(aValue) { return { value: aValue }; }

JavaScript objects

var foo = { prop1: "value1" };

var bar = {
  prop1: "value1",
  prop2: "value2"

Constructors for objects should be capitalized and use Pascal Case:

function ObjectConstructor() { = "bar";

Mode line

Files should have Emacs and vim mode line comments as the first two lines of the file, which should set indent-tabs-mode to nil. For new files, use the following, specifying two-space indentation:

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at */

Be sure to use the correct "Mode" in the first line, don't use "C++" in JavaScript files. The exception to this is in Python code, in which we use four spaces for indentations.


In general, snuggle pointer stars with the type, not the variable name:

T* p; // GOOD
T *p; // BAD
T* p, q; // OOPS put these on separate lines

Some existing modules still use the T *p style.


In C++, when breaking lines containing overlong expressions, binary operators must be left on their original lines if the line break happens around the operator.  The second line should start in the same column as the start of the expression in the first line.

In JavaScript, overlong expressions not joined by && and || should break so the operator starts on the second line and starting in the same column as the beginning of the expression in the first line. This applies to ?:, binary arithmetic operators including +, and member-of operators. Rationale: an operator at the front of the continuation line makes for faster visual scanning, as there is no need to read to the end of line. Also there exists a context-sensitive keyword hazard in JavaScript; see bug 442099, comment 19, which can be avoided by putting . at the start of a continuation line, in long member expression.

In JavaScript, == is preferred to ===.

Unary keyword operators, such as typeof and sizeof, should have their operand parenthesized; e.g. typeof("foo") == "string".


Double-quoted strings (e.g. "foo") are preferred to single-quoted strings (e.g. 'foo'), in JavaScript, except to avoid escaping embedded double quotes, or when assigning inline event handlers.

Use \uXXXX unicode escapes for non-ASCII characters. The character set for XUL, DTD, script, and properties files is UTF-8, which is not easily readable.


Follow these naming prefix conventions:

Variable prefixes
  • k=constant (e.g. kNC_child). Not all code uses this style; some uses ALL_CAPS for constants.
  • g=global (e.g. gPrefService)
  • a=argument (e.g. aCount)
  • C++ Specific Prefixes
    • s=static member (e.g. sPrefChecked)
    • m=member (e.g. mLength)
    • e=enum variants (e.g. enum Foo { eBar, eBaz }). Enum classes should use `CamelCase` instead (e.g. enum class Foo { Bar, Baz }).
  • JavaScript Specific Prefixes
    • _=member (variable or function) (e.g. _length or _setType(aType))
    • k=enumeration value (e.g. const kDisplayModeNormal = 0)
    • on=event handler (e.g. function onLoad())
    • Convenience constants for interface names should be prefixed with nsI:
      const nsISupports = Components.interfaces.nsISupports;
      const nsIWBN = Components.interfaces.nsIWebBrowserNavigation;
Global functions/macros/etc
  • Macros begin with MOZ_, and are all caps (e.g. MOZ_WOW_GOODNESS). Note that older code uses the NS_ prefix; while these aren't being changed, you should only use MOZ_ for new macros. The only exception is if you're creating a new macro, which is part of a set of related macros still using the old NS_ prefix. Then you should be consistent with the existing macros.
Error Variables
  • local nsresult result codes should be `rv`. `rv` should not be used for bool or other result types.
  • local bool result codes should be `ok`

General practices

  • Don't put an else right after a return (or a break). Delete the else, it's unnecessary and increases indentation level.
  • Don't leave debug printfs or dumps lying around.
  • Use Unix-style carriage returns ("\n"), rather than Windows/DOS ones ("\r\n").  You can convert patches, with DOS newlines to Unix via the 'dos2unix' utility, or your favorite text editor.
  • Use two spaces for indentation.
  • Use JavaDoc-style comments.
  • When fixing a problem, check to see if the problem occurs elsewhere in the same file, and fix it everywhere if possible.
  • End the file with a newline. Make sure your patches don't contain files with the text "no newline at end of file" in them.
  • Declare local variables as near to their use as possible.
  • For new files, be sure to use the right license boilerplate, per our license policy.

C/C++ practices

  • Have you checked for compiler warnings? Warnings often point to real bugs.
  • In C++ code, use nullptr for pointers. In C code, using NULL or 0 is allowed.
  • Don't use PRBool and PRPackedBool in C++, use bool instead.
  • For checking if a std container has no items, don't use size(), instead use empty().
  • When testing a pointer, use (!myPtr) or (myPtr); don't use myPtr != nullptr or myPtr == nullptr.
  • Do not compare x == true or x == false. Use (x) or (!x) instead. x == true, is certainly different from if (x)!
  • In general, initialize variables with nsFoo aFoo = bFoo, and not nsFoo aFoo(bFoo).
    • For constructors, initialize member variables with : nsFoo aFoo(bFoo) syntax.
  • To avoid warnings created by variables used only in debug builds, use the DebugOnly<T> helper when declaring them.
  • You should use the static preference API for working with preferences.
  • One-argument constructors, that are not copy or move constructors, should generally be marked explicit.  Exceptions should be annotated with MOZ_IMPLICIT.
  • Use char32_t as the return type or argument type of a method that returns or takes as argument a single Unicode scalar value. (Don't use UTF-32 strings, though.)
  • Don't use functions from ctype.h (isdigit(), isalpha(), etc.) or from strings.h (strcasecmp(), strncasecmp()). These are locale-sensitive, which makes them inappropriate for processing protocol text. At the same time, they are too limited to work properly for processing natural-language text. Use the alternatives in mozilla/TextUtils.h and in nsUnicharUtils.h in place of ctype.h. In place of strings.h, prefer the nsStringComparator facilities for comparing strings or if you have to work with zero-terminated strings, use nsCRT.h for ASCII-case-insensitive comparison.
  • Forward-declare classes in your header files, instead of including them, whenever possible. For example, if you have an interface with a void DoSomething(nsIContent* aContent) function, forward-declare with class nsIContent; instead of #include "nsIContent.h"
  • Includes are split into three blocks, and sorted alphabetically in each block:
    1. The main header: #include "Foo.h" in Foo.cpp
    2. Standard library includes: #include <map>
    3. Mozilla includes: #include "mozilla/dom/Element.h"
  • Include guards are named by determining the fully-qualified include path, then substituting _ for / and . and - in it. For example, nsINode.h's guard is nsINode_h, and Element.h's guard is mozilla_dom_Element_h (because its include path is mozilla/dom/Element.h).

    Use the following exact form for include guards. GCC, and clang, recognize this idiom and avoid re-reading headers that use it. To avoid confusing GCC's and clang's header optimization, do not include any code before or after the include guards (comments and whitespace are OK). Do not combine any other preprocessor checks in the #ifndef <guard> expression.

    #ifndef <guard>
    #define <guard>
    ... All code ...
    #endif // <guard>

JavaScript practices

  • Make sure you are aware of the JavaScript Tips.
  • Do not compare x == true or x == false. Use (x) or (!x) instead. x == true, is certainly different from if (x)! Compare objects to null, numbers to 0 or strings to "", if there is chance for confusion.
  • Make sure that your code doesn't generate any strict JavaScript warnings, such as:
    • Duplicate variable declaration.
    • Mixing return; with return value;
    • Undeclared variables or members. If you are unsure if an array value exists, compare the index to the array's length. If you are unsure if an object member exists, use "name" in aObject, or if you are expecting a particular type you may use typeof( == "function" (or whichever type you are expecting).
  • Use [value1, value2] to create a JavaScript array in preference to using new Array(value1, value2) which can be confusing, as new Array(length) will actually create a physically empty array with the given logical length, while [value] will always create a 1-element array. You cannot actually guarantee to be able to preallocate memory for an array.
  • Use { member: value, ... } to create a JavaScript object; a useful advantage over new Object() is the ability to create initial properties and use extended JavaScript syntax, to define getters and setters.
  • If having defined a constructor you need to assign default properties, it is preferred to assign an object literal to the prototype property.
  • Use regular expressions, but use wisely. For instance, to check that aString is not completely whitespace use /\S/.test(aString). Only use if you need to know the position of the result, or aString.match if you need to collect matching substrings (delimited by parentheses in the regular expression). Regular expressions are less useful if the match is unknown in advance, or to extract substrings in known positions in the string. For instance, aString.slice(-1) returns the last letter in aString, or the empty string if aString is empty.

Java practices

  • We use the Java Coding Style. Quick summary:
    • FirstLetterUpperCase for class names.
    • camelCase for method and variable names.
    • One declaration per line:
      int x, y; // this is BAD!
      int a;    // split it over
      int b;    // two lines
  • Braces should be placed like so (generally, opening braces on same line, closing braces on a new line):
    public void func(int arg) {
        if (arg != 0) {
            while (arg > 0) {
        } else {
  • Places we differ from the Java coding style:
    • Start class variable names with 'm' prefix (e.g. mSomeClassVariable) and static variables with 's' prefix (e.g. sSomeStaticVariable)
    • import statements:
      • Do not use wildcard imports like `import java.util.*;`
      • Organize imports by blocks separated by empty line: org.mozilla.*, com.*, net.*, org.*, android.*, then java.*
      • Within each import block, alphabetize import names with uppercase before lowercase. For example, com.example.Foo is before
    • 4-space indents.
    • Spaces, not tabs.
    • Don't restrict yourself to 80-character lines. Google's Android style guide suggests 100-character lines, which is also the default setting in Android Studio. Java code tends to be long horizontally, so use appropriate judgement when wrapping. Avoid deep indents on wrapping. Note that aligning the wrapped part of a line, with some previous part of the line (rather than just using a fixed indent), may require shifting the code every time the line changes, resulting in spurious whitespace changes.
  • For additional specifics on Firefox for Android, see the Coding Style guide for Firefox on Android.
  • The Android Coding Style has some useful guidelines too.

Makefile/ practices

  • Changes to makefile and variables do not require build-config peer review. Any other build system changes, such as adding new scripts or rules, require review from the build-config team.
  • Suffix long if/endif conditionals with #{ & #}, so editors can display matched tokens enclosing a block of statements.
    ifdef CHECK_TYPE #{
      ifneq ($(flavor var_type),recursive) #{
        $(warning var should be expandable but detected var_type=$(flavor var_type))
      endif #}
    endif #}
  • are python and follow normal Python style.
  • List assignments should be written with one element per line.  Align closing square brace with start of variable assignment. If ordering is not important, variables should be in alphabetical order.
    var += [
  • Use CONFIG['CPU_ARCH'] {=arm} to test for generic classes of architecure rather than CONFIG['OS_TEST'] {=armv7} (re: bug 886689).

Python practices

  • Install the mozext Mercurial extension, and address every issue reported on commit, qrefresh, or the output of hg critic.
  • Follow PEP 8.
  • Do not place statements on the same line as if/elif/else conditionals to form a one-liner.
  • Global vars, please avoid them at all cost.
  • Exclude outer parenthesis from conditionals.  Use if x > 5:, rather than if (x > 5):
  • Use string formatters, rather than var + str(val).  var = 'Type %s value is %d' % ('int', 5).
  • Utilize tools like pylint or pychecker to screen sources for common problems.
  • Testing/Unit tests, please write them.
  • See David Goodger, Code Like a Pythonista: Idiomatic Python.

SVG practices

Check SVG Guidelines for more details.

COM, pointers and strings

  • Use nsCOMPtr<>
    If you don't know how to use it, start looking in the code for examples. The general rule, is that the very act of typing NS_RELEASE should be a signal to you to question your code: "Should I be using nsCOMPtr here?". Generally the only valid use of NS_RELEASE, are when you are storing refcounted pointers in a long-lived datastructure.
  • Declare new XPCOM interfaces using XPIDL, so they will be scriptable.
  • Use nsCOMPtr for strong references, and nsWeakPtr for weak references.
  • String arguments to functions should be declared as nsAString.
  • Use EmptyString() and EmptyCString() instead of NS_LITERAL_STRING("") or nsAutoString empty;.
  • Use str.IsEmpty() instead of str.Length() == 0.
  • Use str.Truncate() instead of str.SetLength(0) or str.Assign(EmptyString()).
  • Don't use QueryInterface directly. Use CallQueryInterface or do_QueryInterface instead.
  • nsresult should be declared as rv. Not res, not result, not foo.
  • For constant strings, use NS_LITERAL_STRING("...") instead of NS_ConvertASCIItoUCS2("..."), AssignWithConversion("..."), EqualsWithConversion("..."), or nsAutoString()
  • To compare a string with a literal, use .EqualsLiteral("...").
  • Use Contract IDs, instead of CIDs with do_CreateInstance/do_GetService.
  • Use pointers, instead of references for function out parameters, even for primitive types.


Use leading-lowercase, or "interCaps"

When defining a method or attribute in IDL, the first letter should be lowercase, and each following word should be capitalized. For example:

long updateStatusBar();

Use attributes wherever possible

Whenever you are retrieving or setting a single value, without any context, you should use attributes. Don't use two methods when you could use an attribute. Using attributes logically connects the getting and setting of a value, and makes scripted code look cleaner.

This example has too many methods:

interface nsIFoo : nsISupports
    long getLength();
    void setLength(in long length);
    long getColor();

The code below will generate the exact same C++ signature, but is more script-friendly.

interface nsIFoo : nsISupports
    attribute long length;
    readonly attribute long color;

Use Java-style constants

When defining scriptable constants in IDL, the name should be all uppercase, with underscores between words:


See also

For details on interface development, as well as more detailed style guides, see the Interface development guide.

Error handling

Check for errors early and often

Every time you make a call into an XPCOM function, you should check for an error condition. You need to do this even if you know that call will never fail. Why?

  • Someone may change the callee in the future to return a failure condition.
  • The object in question may live on another thread, another process, or possibly even another machine. The proxy could have failed to make your call in the first place.

Also, when you make a new function which is failable (i.e. it will return a nsresult or a bool that may indicate an error), you should explicitly mark the return value should always be checked. For example:

// for IDL.
[must_use] nsISupports

// for C++, add this in *declaration*, do not add it again in implementation.
MOZ_MUST_USE nsresult

There are some exceptions:

  • Predicates or getters, which return bool or nsresult.
  • IPC method implementation (For example, bool RecvSomeMessage()).
  • Most callers will check the output parameter, see below.
SomeMap::GetValue(const nsString& key, nsString& value);

If most callers need to check the output value first, then adding MOZ_MUST_USE might be too verbose. In this case, change the return value to void might be a reasonable choice.

There is also a static analysis attribute MOZ_MUST_USE_TYPE, which can be added to class declarations, to ensure that those declarations are always used when they are returned.

Use the NS_WARN_IF macro when errors are unexpected.

The NS_WARN_IF macro can be used to issue a console warning, in debug builds if the condition fails. This should only be used when the failure is unexpected and cannot be caused by normal web content.

If you are writing code which wants to issue warnings when methods fail, please either use NS_WARNING directly, or use the new NS_WARN_IF macro.

if (NS_WARN_IF(somethingthatshouldbefalse)) {

if (NS_WARN_IF(NS_FAILED(rv))) {
  return rv;

Previously, the NS_ENSURE_* macros were used for this purpose, but those macros hide return statements, and should not be used in new code. (This coding style rule isn't generally agreed, so use of NS_ENSURE_* can be valid.)

Return from errors immediately

In most cases, your knee-jerk reaction should be to return from the current function, when an error condition occurs. Don't do this:

rv = foo->Call1();
if (NS_SUCCEEDED(rv)) {
  rv = foo->Call2();
  if (NS_SUCCEEDED(rv)) {
    rv = foo->Call3();
return rv;

Instead, do this:

rv = foo->Call1();
if (NS_FAILED(rv)) {
  return rv;

rv = foo->Call2();
if (NS_FAILED(rv)) {
  return rv;

rv = foo->Call3();
if (NS_FAILED(rv)) {
  return rv;

Why? Error handling should not obfuscate the logic of the code. The author's intent, in the first example, was to make 3 calls in succession. Wrapping the calls in nested if() statements, instead obscured the most likely behavior of the code.

Consider a more complicated example to hide a bug:

bool val;
rv = foo->GetBooleanValue(&val);
if (NS_SUCCEEDED(rv) && val) {
} else {

The intent of the author, may have been, that foo->Call2() would only happen when val had a false value. In fact, foo->Call2() will also be called, when foo->GetBooleanValue(&val) fails. This may, or may not, have been the author's intent. It is not clear from this code. Here is an updated version:

bool val;
rv = foo->GetBooleanValue(&val);
if (NS_FAILED(rv)) {
  return rv;
if (val) {
} else {

In this example, the author's intent is clear, and an error condition avoids both calls to foo->Call1() and foo->Call2();

Possible exceptions: Sometimes it is not fatal if a call fails. For instance, if you are notifying a series of observers that an event has fired, it might be trivial that one of these notifications failed:

for (size_t i = 0; i < length; ++i) {
  // we don't care if any individual observer fails
  observers[i]->Observe(foo, bar, baz);

Another possibility, is you are not sure if a component exists or is installed, and you wish to continue normally, if the component is not found.

nsCOMPtr<nsIMyService> service = do_CreateInstance(NS_MYSERVICE_CID, &rv);
// if the service is installed, then we'll use it.
if (NS_SUCCEEDED(rv)) {
  // non-fatal if this fails too, ignore this error.

  // this is important, handle this error!
  rv = service->DoSomethingImportant();
  if (NS_FAILED(rv)) {
    return rv;
// continue normally whether or not the service exists.

C++ strings

Use the Auto form of strings for local values

When declaring a local, short-lived nsString class, always use nsAutoString or nsAutoCString. These pre-allocate a 64-byte buffer on the stack, and avoid fragmenting the heap. Don't do this:

  nsCString bar;


  nsAutoCString bar;

Be wary of leaking values from non-XPCOM functions that return char* or PRUnichar*

It is an easy trap to return an allocated string, from an internal helper function, and then using that function inline in your code, without freeing the value. Consider this code:

static char*
  return resultString.ToNewCString();


In the above example, WarnUser will get the string allocated from resultString.ToNewCString(), and throw away the pointer. The resulting value is never freed. Instead, either use the string classes, to make sure your string is automatically freed when it goes out of scope, or make sure that your string is freed.

Automatic cleanup:

static void
GetStringValue(nsAWritableCString& aResult)
  aResult.Assign("resulting string");

  nsAutoCString warning;

Free the string manually:

static char*
  return resultString.ToNewCString();

  char* warning = GetStringValue();

Use MOZ_UTF16() or NS_LITERAL_STRING() to avoid runtime string conversion

It is very common to need to assign the value of a literal string, such as "Some String", into a unicode buffer. Instead of using nsString's AssignLiteral and AppendLiteral, use NS_LITERAL_STRING(), instead. On most platforms, this will force the compiler to compile in a raw unicode string, and assign it directly.


nsAutoString warning;
warning.AssignLiteral("danger will robinson!");


NS_NAMED_LITERAL_STRING(warning, "danger will robinson!");
// if you'll be using the 'warning' string, you can still use it as before:

// alternatively, use the wide string directly:
foo->SetStringValue(NS_LITERAL_STRING("danger will robinson!"));
bar->SetUnicodeValue(MOZ_UTF16("danger will robinson!"));

Note: Named literal strings cannot yet be static.

Usage of PR_(MAX|MIN|ABS|ROUNDUP) macro calls

Use the standard-library functions (std::max), instead of PR_(MAX|MIN|ABS|ROUNDUP).

Use mozilla::Abs instead of PR_ABS. All PR_ABS calls in C++ code have been replaced with mozilla::Abs calls, in bug 847480. All new code in Firefox/core/toolkit needs to #include "nsAlgorithm.h", and use the NS_foo variants instead of PR_foo, or #include "mozilla/MathAlgorithms.h" for mozilla::Abs.