Coding Style

  • Revision slug: Developer_Guide/Coding_Style
  • Revision title: Coding Style
  • Revision id: 7312
  • Created:
  • Creator: Benjamin Smedberg
  • Is current revision? No
  • Comment Fix bracing...; 33 words added, 30 words removed

Revision Content

This document attempts to explain the basic styles and patterns that are used in the Mozilla codebase. New code should try to conform to these standards so that it is as easy to maintain as existing code. Of course every rule has an exception, but it's important to know the rules nonetheless!

This is particularly directed at people new to the Mozilla codebase, who are in the process of getting their code reviewed. Before getting a review, please read over this document and make sure your code conforms to the recommendations here.

General C/C++ Practices

  • Have you checked for compiler warnings? Warnings often point to real bugs.
  • Are the changes 64-bit clean?
  • Do the changes meet the C++ Portability Guide
  • Don't use NULL for pointers. On some systems it's declared as void * and causes a compile warning when assigned to a pointer. Use 0 or nsnull instead.
  • When testing a pointer, use !myPtr or (myPtr); don't use myPtr != nsnull or myPtr == nsnull.
  • Do not compare == PR_TRUE or PR_FALSE. Use (x) or (!x) instead. == PR_TRUE, in fact, is *different* from if (x)!
  • Don't put an else right after a return. Delete the else, it's unnecessary and increases indentation level.
  • Always check the return value of new for null.
  • Don't leave debug printf()s lying around.
  • Use JavaDoc-style comments in any new class header files.
  • When fixing a problem, check to see if the problem occurs elsewhere in the same file, and fix it everywhere if possible.
  • On whether to use nsFoo aFoo (bFoo) or nsFoo aFoo = bFoo: For first tier platforms, although the former is theoretically better, there is probably no reason to prefer it over the latter form. This is good, since everyone agrees, the form with "=" looks better. More data for second tier platforms would be good.
  • 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"

COM and pointers

  • 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 str.IsEmpty() instead of str.Length() == 0.
  • 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()
  • Use contractids instead of progids or class IDs.

IDL

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 one 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:

const long ERROR_UNDEFINED_VARIABLE = 1;

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 actually make your call in the first place.

Use the nice macros

Use the NS_ENSURE_SUCCESS(rv, rv) and NS_ENSURE_TRUE(expr, rv) macros in place of if (NS_FAILED(rv)) { return rv; } and if (!expr) { return rv; }, unless the failure is a normal condition (i.e. you don't want it to warn on a debug build).

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();
NS_ENSURE_SUCCESS(rv, rv);

rv = foo->Call2();
NS_ENSURE_SUCCESS(rv, rv);

rv = foo->Call3();
NS_ENSURE_SUCCESS(rv, rv);

Why? Because 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, but wrapping the calls in nested if() statements obscured the most likely behavior of the code.

Consider a more complicated example that actually hides a bug:

PRBool val;
rv = foo->GetBooleanValue(&val);
if (NS_SUCCEEDED(rv) && val)
    foo->Call1();
else
    foo->Call2();

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, and it is not clear from this code. Here is an updated version:

PRBool val;
rv = foo->GetBooleanValue(&val);
if (NS_FAILED(rv)) return rv;
if (val)
    foo->Call1();
else
    foo->Call2();

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 inconsequential that one of these notifications failed:

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

Another possibility is that 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
    service->DoSomething();

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

Strings

Use the Auto form of strings for local values

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

nsresult foo() {
  nsCString bar;
  ..
}

instead:

nsresult foo() {
  nsCAutoString 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 use that function inline in your code without freeing the value. Consider this code:

static char *GetStringValue() {
    ..
    return resultString.ToNewCString();
}

    ..
    WarnUser(GetStringValue());

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");
}

    ..
    nsCAutoString warning;
    GetStringValue(warning);
    WarnUser(warning.get());

Free the string manually:

static char *GetStringValue() {
    ..
    return resultString.ToNewCString();
}

    ..
    char *warning = GetStringValue();
    WarnUser(warning);
    nsMemory::Free(warning);

Use 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 AssignWithConversion and AppendWithConversion, use NS_LITERAL_STRING() instead. On most platforms, this will force the compiler to compile in a raw unicode string, and assign it directly.

Incorrect:

nsAutoString warning; warning.AssignWithConversion("danger will robinson!");
..
foo->SetUnicodeValue(warning.get());

Correct:

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

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

Naming and Formatting code

Note: the following is not all set in stone, this is interim to give people a chance to look

Use the prevailing style in a file or module, or ask the owner, if you are on someone else's turf. Module owner rules all.

Whitespace

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

Line Length

80 characters or less (for Bonsai and printing).

Control Structures

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;
    break;
  }
  case 2:
    ...
    break;
  default:
    break;
}

Control keywords "if", "for", "while", and "switch" are always followed by a space to distinguish them from function calls which have no trailing space. 

Namespaces

Mozilla project C++ declarations should be in the "mozilla" namespace. Modules can define their own namespaces under "mozilla", with short all-lowercase names, but are allowed to add declarations to the "mozilla" namespace.

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.)  Introduce typedefs so as to avoid writing namespace-prefixed type names in non-namespaced classes. For example:

class MyClass {
public:
  typedef mozilla::TimeStamp TimeStamp;
  TimeStamp mStartTime;
  TimeStamp mEndTime;
};

Be wise about the visibility of these typedefs.  They should be private or protected unless there's a good reason to make them public.  For example, a public Array::size_type makes sense, but a public MyClass::TimeStamp above probably doesn't.

"using namespace ...;" is only allowed in .cpp files after all #includes. Prefer to wrap code in "namespace ... { ... };" instead if possible.

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

(c-set-offset 'innamespace 0)

 

Classes 

namespace mozilla {
class MyClass : public X,
                public Y
{
public:
  MyClass() : mVar(0) { ... };
  
private:
  int mVar;
};
}

Existing classes in the global namespace are named with a short prefix (e.g. "ns") as a psuedo-namespace.

For small functions in a class declaration, it's OK to do the above. For larger ones use something similar to method declarations below.

Methods

int
MyClass::Method(...)
{
  ...
}

Mode Line

Files should have an Emacs mode line comment as the first line of the file, which should set indent-tabs-mode to nil. For new files, use this, specifying 2-space indentation:

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */

Operators

should be at the end of a line, not the beginning of the next, if an operator is at a line break.

Prefixes

Follow naming prefix conventions.

Variable prefixes
  • k=constant (e.g. kNC_child)
  • g=global (e.g. gPrefService)
  • m=member (e.g. mLength)
  • a=argument (e.g. aCount)
  • s=static member (e.g. sPrefChecked)
Global functions/macros/etc
  • Macros begin with NS_, and are all caps (e.g. NS_IMPL_ISUPPORTS)
  • Global (exported) functions begin with NS_ and use LeadingCaps (e.g. NS_NewISupportsArray). Functions in the global namespace do not need NS_.

Original Document Information

{{ languages( { "ja": "ja/Mozilla_Coding_Style_Guide" } ) }}

Revision Source

<p>This document attempts to explain the basic styles and patterns that are used in the Mozilla codebase. New code should try to conform to these standards so that it is as easy to maintain as existing code. Of course every rule has an exception, but it's important to know the rules nonetheless!</p>
<p>This is particularly directed at people new to the Mozilla codebase, who are in the process of getting their code reviewed. Before getting a review, please read over this document and make sure your code conforms to the recommendations here.</p>
<h3 name="General_C.2FC.2B.2B_Practices">General C/C++ Practices</h3>
<ul> <li>Have you checked for compiler warnings? Warnings often point to real bugs.</li> <li>Are the changes <a class="external" href="http://www.testdrive.hp.com/">64-bit clean?</a></li> <li>Do the changes meet the <a href="/en/C%2B%2B_Portability_Guide" title="en/C++_Portability_Guide">C++ Portability Guide</a></li> <li>Don't use NULL for pointers. On some systems it's declared as <code>void *</code> and causes a compile warning when assigned to a pointer. Use 0 or nsnull instead.</li> <li>When testing a pointer, use !myPtr or (myPtr); don't use myPtr != nsnull or myPtr == nsnull.</li> <li>Do not compare == PR_TRUE or PR_FALSE. Use (x) or (!x) instead. == PR_TRUE, in fact, is *different* from if (x)!</li> <li>Don't put an else right after a return. Delete the else, it's unnecessary and increases indentation level.</li> <li>Always check the return value of <code>new</code> for null.</li> <li>Don't leave debug printf()s lying around.</li> <li>Use <a class="external" href="http://java.sun.com/j2se/javadoc/writingdoccomments/">JavaDoc-style comments</a> in any new class header files.</li> <li>When fixing a problem, check to see if the problem occurs elsewhere in the same file, and fix it everywhere if possible.</li> <li>On whether to use <code>nsFoo aFoo (bFoo)</code> or <code>nsFoo aFoo = bFoo</code>: For first tier platforms, although the former is theoretically better, there is probably no reason to prefer it over the latter form. This is good, since everyone agrees, the form with "=" looks better. More data for second tier platforms would be good.</li> <li>Forward declare classes in your header files instead of including them whenever possible. For example, if you have an interface with a <code>void DoSomething(nsIContent* aContent)</code> function, forward declare with <code>class nsIContent;</code> instead of <code>#include "nsIContent.h"</code></li>
</ul>
<h3 name="COM_and_pointers">COM and pointers</h3>
<ul> <li>Use <code>nsCOMPtr&lt;&gt;</code><br> 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 <code>NS_RELEASE</code> should be a signal to you to question your code: "Should I be using <code>nsCOMPtr</code> here?". Generally the only valid use of <code>NS_RELEASE</code> are when you are storing refcounted pointers in a long-lived datastructure.</li> <li>Declare new XPCOM interfaces using <a href="/en/XPIDL" title="en/XPIDL">XPIDL</a> so they will be scriptable.</li> <li>Use <a href="/en/nsCOMPtr" title="en/nsCOMPtr">nsCOMPtr</a> for strong references, and <a href="/en/Weak_reference" title="en/Weak_reference">nsWeakPtr</a> for weak references.</li> <li>String arguments to functions should be declared as <code>nsAString</code>.</li> <li>Use <code>str.IsEmpty()</code> instead of <code>str.Length() == 0</code>.</li> <li>Don't use <code>QueryInterface</code> directly. Use <code>CallQueryInterface</code> or <code>do_QueryInterface</code> instead.</li> <li>nsresult should be declared as rv. Not res, not result, not foo.</li> <li>For constant strings, use <code>NS_LITERAL_STRING("...")</code> instead of <code>NS_ConvertASCIItoUCS2("...")</code>, <code>AssignWithConversion("...")</code>, <code>EqualsWithConversion("...")</code>, or <code>nsAutoString()</code></li> <li>Use <a class="link-news" href="news://news.mozilla.org/3994AE3E.D96EF810%40netscape.com">contractids</a> instead of progids or class IDs.</li>
</ul>
<h3 name="IDL">IDL</h3>
<h4 name="Use_leading-lowercase.2C_or_.22interCaps.22">Use leading-lowercase, or "interCaps"</h4>
<p>When defining a method or attribute in IDL, the first letter should be lowercase, and each following word should be capitalized. For example:</p>
<pre>long updateStatusBar();
</pre>
<h4 name="Use_attributes_wherever_possible">Use attributes wherever possible</h4>
<p>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 one attribute. Using attributes logically connects the getting and setting of a value, and makes scripted code look cleaner.</p>
<p>This example has too many methods:</p>
<pre>interface nsIFoo : nsISupports {
    long getLength();
    void setLength(in long length);
    long getColor();
};
</pre>
<p>The code below will generate the exact same C++ signature, but is more script-friendly.</p>
<pre>interface nsIFoo : nsISupports {
    attribute long length;
    readonly attribute long color;
};
</pre>
<h4 name="Use_java-style_constants">Use java-style constants</h4>
<p>When defining scriptable constants in IDL, the name should be all uppercase, with underscores between words:</p>
<pre>const long ERROR_UNDEFINED_VARIABLE = 1;
</pre>
<h3 name="Error_handling">Error handling</h3>
<h4 name="Check_for_errors_early_and_often">Check for errors early and often</h4>
<p>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?</p>
<ul> <li>Someone may change the callee in the future to return a failure condition.</li> <li>The object in question may live on another thread, another process, or possibly even another machine. The proxy could have failed to actually make your call in the first place.</li>
</ul>
<h4 name="Use_the_nice_macros">Use the nice macros</h4>
<p>Use the <code>NS_ENSURE_SUCCESS(rv, rv)</code> and <code>NS_ENSURE_TRUE(expr, rv)</code> macros in place of <code>if (NS_FAILED(rv)) { return rv; }</code> and <code>if (!expr) { return rv; }</code>, <em>unless</em> the failure is a normal condition (i.e. you don't want it to warn on a debug build).</p>
<h4 name="Return_from_errors_immediately">Return from errors immediately</h4>
<p>In most cases, your knee-jerk reaction should be to return from the current function when an error condition occurs. Don't do this:</p>
<pre>rv = foo-&gt;Call1();
if (NS_SUCCEEDED(rv)) {
  rv = foo-&gt;Call2();
  if (NS_SUCCEEDED(rv)) {
    rv = foo-&gt;Call3();
  }
}
return rv;
</pre>
<p>Instead, do this:</p>
<pre>rv = foo-&gt;Call1();
NS_ENSURE_SUCCESS(rv, rv);

rv = foo-&gt;Call2();
NS_ENSURE_SUCCESS(rv, rv);

rv = foo-&gt;Call3();
NS_ENSURE_SUCCESS(rv, rv);
</pre>
<p>Why? Because 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, but wrapping the calls in nested if() statements obscured the most likely behavior of the code.</p>
<p>Consider a more complicated example that actually hides a bug:</p>
<pre>PRBool val;
rv = foo-&gt;GetBooleanValue(&amp;val);
if (NS_SUCCEEDED(rv) &amp;&amp; val)
    foo-&gt;Call1();
else
    foo-&gt;Call2();
</pre>
<p>The intent of the author may have been that foo-&gt;Call2() would only happen when val had a false value. In fact, foo-&gt;Call2() will also be called when foo-&gt;GetBooleanValue(&amp;val) fails. This may or may not have been the author's intent, and it is not clear from this code. Here is an updated version:</p>
<pre>PRBool val;
rv = foo-&gt;GetBooleanValue(&amp;val);
if (NS_FAILED(rv)) return rv;
if (val)
    foo-&gt;Call1();
else
    foo-&gt;Call2();
</pre>
<p>In this example, the author's intent is clear, and an error condition avoids both calls to foo-&gt;Call1() and foo-&gt;Call2();</p>
<p><em>Possible exceptions:</em> 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 inconsequential that one of these notifications failed:</p>
<pre>for (i=0; i&lt;length; i++) {
    // we don't care if any individual observer fails
    observers[i]-&gt;Observe(foo, bar, baz);
}
</pre>
<p>Another possibility is that you are not sure if a component exists or is installed, and you wish to continue normally if the component is not found.</p>
<pre>nsCOMPtr&lt;nsIMyService&gt; service = do_CreateInstance(NS_MYSERVICE_CID, &amp;rv);
// if the service is installed, then we'll use it
if (NS_SUCCEEDED(rv)) {
    // non-fatal if this fails too, ignore this error
    service-&gt;DoSomething();

    // this is important, handle this error!
    rv = service-&gt;DoSomethingImportant();
    if (NS_FAILED(rv)) return rv;
}
    
// continue normally whether or not the service exists
</pre>
<h3 name="Strings">Strings</h3>
<h4 name="Use_the_Auto_form_of_strings_for_local_values">Use the <code>Auto</code> form of strings for local values</h4>
<p>When declaring a local, short-lived nsString class, always use nsAutoString or nsCAutoString - these versions pre-allocate a 64-byte buffer on the stack, and avoid fragmenting the heap. Don't do this:</p>
<pre>nsresult foo() {
  nsCString bar;
  ..
}
</pre>
<p>instead:</p>
<pre>nsresult foo() {
  nsCAutoString bar;
  ..
}
</pre>
<h4 name="Be_wary_of_leaking_values_from_non-XPCOM_functions_that_return_char.2A_or_PRUnichar.2A">Be wary of leaking values from non-XPCOM functions that return char* or PRUnichar*</h4>
<p>It is an easy trap to return an allocated string from an internal helper function, and then use that function inline in your code without freeing the value. Consider this code:</p>
<pre>static char *GetStringValue() {
    ..
    return resultString.ToNewCString();
}

    ..
    WarnUser(GetStringValue());
</pre>
<p>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.</p>
<p>Automatic cleanup:</p>
<pre>static void GetStringValue(nsAWritableCString&amp; aResult) {
    ..
    aResult.Assign("resulting string");
}

    ..
    nsCAutoString warning;
    GetStringValue(warning);
    WarnUser(warning.get());
</pre>
<p>Free the string manually:</p>
<pre>static char *GetStringValue() {
    ..
    return resultString.ToNewCString();
}

    ..
    char *warning = GetStringValue();
    WarnUser(warning);
    nsMemory::Free(warning);
</pre>
<h4 name="Use_NS_LITERAL_STRING.28.29_to_avoid_runtime_string_conversion">Use NS_LITERAL_STRING() to avoid runtime string conversion</h4>
<p>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 AssignWithConversion and AppendWithConversion, use NS_LITERAL_STRING() instead. On most platforms, this will force the compiler to compile in a raw unicode string, and assign it directly.</p>
<p>Incorrect:</p>
<pre>nsAutoString warning; warning.AssignWithConversion("danger will robinson!");
..
foo-&gt;SetUnicodeValue(warning.get());
</pre>
<p>Correct:</p>
<pre>NS_NAMED_LITERAL_STRING(warning,"danger will robinson!");
..
// if you'll be using the 'warning' string, you can still use it as before:
foo-&gt;SetUnicodeValue(warning.get());

// alternatively, use the wide string directly:
foo-&gt;SetUnicodeValue(NS_LITERAL_STRING("danger will robinson!").get());
</pre>
<h3 name="Naming_and_Formatting_code">Naming and Formatting code</h3>
<div class="note">
<p>Note: the following is not all set in stone, this is interim to give people a chance to look</p>
</div>
<p><em>Use the prevailing style in a file or module, or ask the owner, if you are on someone else's turf. Module owner rules all.</em></p>
<h4 name="Whitespace">Whitespace</h4>
<p>No tabs. No whitespace at the end of a line.</p>
<h4 name="Line_Length">Line Length</h4>
<p>80 characters or less (for Bonsai and printing).</p>
<h4 name="Control_Structures">Control Structures</h4>
<pre>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;
    break;
  }
  case 2:
    ...
    break;
  default:
    break;
}</pre>
<p>Control keywords "if", "for", "while", and "switch" are always followed by a space to distinguish them from function calls which have no trailing space. </p><h4 name="Namespaces">Namespaces</h4>
<p>Mozilla project C++ declarations should be in the "mozilla" namespace. Modules can define their own namespaces under "mozilla", with short all-lowercase names, but are allowed to add declarations to the "mozilla" namespace.</p>
<p>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.)  Introduce typedefs so as to avoid writing namespace-prefixed type names in non-namespaced classes. For example:</p>
<pre>class MyClass {
public:
  typedef mozilla::TimeStamp TimeStamp;
  TimeStamp mStartTime;
  TimeStamp mEndTime;
};
</pre>
<p>Be wise about the visibility of these typedefs.  They should be private or protected unless there's a good reason to make them public.  For example, a public Array::size_type makes sense, but a public MyClass::TimeStamp above probably doesn't.</p>
<p>"using namespace ...;" is only allowed in .cpp files after all #includes. Prefer to wrap code in "namespace ... { ... };" instead if possible.</p>
<p>Don't indent code inside "namespace ... { ... }".  You can prevent this inside emacs by setting the "innamespace" offset:</p>
<pre>(c-set-offset 'innamespace 0)
</pre>
<p> </p><h4 name="Classes">Classes </h4>
<pre>namespace mozilla {
class MyClass : public X,
                public Y
{
public:
  MyClass() : mVar(0) { ... };
  
private:
  int mVar;
};
}

</pre>
<p>Existing classes in the global namespace are named with a short prefix (e.g. "ns") as a psuedo-namespace.</p>
<p>For small functions in a class declaration, it's OK to do the above. For larger ones use something similar to method declarations below.</p>
<h4 name="Methods">Methods</h4>
<pre>int
MyClass::Method(...)
{
  ...
}
</pre>
<h4 name="Mode_Line">Mode Line</h4>
<p>Files should have an Emacs mode line comment as the first line of the file, which should set indent-tabs-mode to nil. For new files, use this, specifying 2-space indentation:</p>
<pre>/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
</pre>
<h4 name="Operators">Operators</h4>
<p>should be at the end of a line, not the beginning of the next, if an operator is at a line break.</p>
<h4 name="Prefixes">Prefixes</h4>
<p>Follow naming prefix conventions.</p>
<h5 name="Variable_prefixes">Variable prefixes</h5>
<ul> <li>k=constant (e.g. <code>kNC_child</code>)</li> <li>g=global (e.g. <code>gPrefService</code>)</li> <li>m=member (e.g. <code>mLength</code>)</li> <li>a=argument (e.g. <code>aCount</code>)</li> <li>s=static member (e.g. <code>sPrefChecked</code>)</li>
</ul>
<h5 name="Global_functions.2Fmacros.2Fetc">Global functions/macros/etc</h5>
<ul> <li>Macros begin with <code>NS_</code>, and are all caps (e.g. <code>NS_IMPL_ISUPPORTS</code>)</li> <li>Global (exported) functions begin with NS_ and use LeadingCaps (e.g. <code>NS_NewISupportsArray</code>). Functions in the global namespace do not need NS_.</li>
</ul>
<div class="originaldocinfo">
<h2 name="Original_Document_Information">Original Document Information</h2>
<ul> <li>Author(s): <a class="link-mailto" href="mailto:alecf@flett.org">Alec Flett</a></li> <li>Other Contributors: Thanks to: pink, smfr, waterson, jband, brendan and rogc for additional comments. Additions by <a class="link-mailto" href="mailto:akkana@netscape.com">Akkana Peck</a> based on discussions on IRC: thanks to: bbaetz, bz, jfrancis, jkeiser, mjudge, and sdagley for comments, and to <a class="external" href="http://www.johnkeiser.com/cgi-bin/jst-review-cgi.pl">John Keiser and JST's Reviewer Simulacrum</a> and <a class="external" href="http://www.mozilla.org/hacking/reviewers.html">Brendan and Mitchell's super-review document</a>.</li> <li>Last Updated Date: February 8, 2005</li> <li>Copyright Information: Portions of this content are © 1998–2007 by individual mozilla.org contributors; content available under a Creative Commons license | <a class="external" href="http://www.mozilla.org/foundation/licensing/website-content.html">Details</a>.</li>
</ul>
</div>
<p>{{ languages( { "ja": "ja/Mozilla_Coding_Style_Guide" } ) }}</p>
Revert to this revision