| <!doctype html public "-//w3c//dtd html 4.0 transitional//en"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <meta http-equiv="CONTENT-TYPE" content="text/html; charset=iso-8859-1"> |
| </head> |
| <body> |
| |
| <table BORDER=0 CELLSPACING=0 CELLPADDING=3 WIDTH="100%" STYLE="page-break-before: always" > |
| <tr> |
| <td VALIGN=TOP> |
| <h1><a NAME="portability_rules"></a>C++ coding guidelines</h1> |
| The <a href="http://www.mozilla.org/hacking/portable-cpp.html">Mozilla |
| C++ portability guidelines</a> provide an excellent source of information |
| on portable C++ programming. Many of these guidelines are direct applicable |
| to coding OpenOffice.org projects and are taken over verbatim into the |
| guidelines below. I've taken out some of the Mozilla rules |
| (don't use exceptions, |
| RTTI and namespaces) which restrict the usage of newer language features. |
| OpenOffice.org can't be compiled with older compilers anyway, and current |
| compilers implement these features properly. I've also added a few rules |
| from our OpenOffice.org programming guidelines. |
| <p>The guidelines are roughly ordered by importance. Guideline 1,2,4,5 |
| cover problems which are almost always present in any mayor build of OpenOffice.org |
| and require sometimes excessive amount of code tweaking by the release |
| engineers. |
| <br> |
| <h2><a NAME="dont_use_static_constructors"></a>Don't use static constructors.</h2> |
| <p>Non-portable example: |
| <pre> |
| FooBarClass static_object(87, 92); |
| |
| void |
| bar() |
| { |
| if (static_object.count > 15) { |
| ... |
| } |
| } |
| </pre> |
| Static constructors don't work reliably either. A static initialized object |
| is an object which is instanciated at startup time (just before <tt>main()</tt> |
| is called). Usually there are two components to these objects. First there |
| is the data segment which is static data loaded into the global data segment |
| of the program. The second part is a initializer function that is called |
| by the loader before <tt>main()</tt> is called. We've found that many compilers |
| do not reliably implement the initializer function. So you get the object |
| data, but it is never initialized. One workaround for this limitation is |
| to write a wrapper function that creates a single instance of an object, |
| and replace all references to the static initialized object with a call |
| to the wrapper function: |
| <p>Portable example: |
| <pre> |
| static FooBarClass* static_object; |
| |
| FooBarClass* |
| getStaticObject() |
| { |
| if (!static_object) |
| static_object = |
| new FooBarClass(87, 92); |
| return static_object; |
| } |
| |
| void |
| bar() |
| { |
| if (getStaticObject()->count > 15) { |
| ... |
| } |
| } |
| </pre> |
| <h2><a NAME="use_common_den"></a>Use the common denominator between members |
| of a C/C++ compiler family.</h2> |
| <p>For many of the compiler families we use, the implementation of the |
| C and C++ compilers are completely different, sometimes this means that |
| there are things you can do in the C language, that you cannot do in the |
| C++ language on the same machine. One example is the 'long long' type. |
| On some systems (IBM's compiler used to be one, but I think it's better |
| now), the C compiler supports long long, while the C++ compiler does not. |
| This can make porting a pain, as often times these types are in header |
| files shared between C and C++ files. The only thing you can do is to go |
| with the common denominator that both compilers support. In the special |
| case of long long, we developed a set of macros for supporting 64 bit integers |
| when the long long type is not available. We have to use these macros if |
| either the C or the C++ compiler does not support the special 64 bit type. |
| <h2><a NAME="no_cpp_comments_in_c"></a>Don't put C++ comments in C code.</h2> |
| <p>The quickest way to raise the blood pressure of a Release engineer is |
| to put C++ comments (<b><tt>//</tt></b> comments) into C files. Yes, this |
| might work on your Microsoft Visual C compiler, but it's wrong, and is |
| not supported by the vast majority of C compilers in the world.<b> Just |
| do not go there.</b> |
| <p>Many header files will be included by C files and included by C++ files. |
| We think it's a good idea to apply this same rule to those headers. Don't |
| put C++ comments in header files included in C files. You might argue that |
| you could use C++ style comments inside <tt>#ifdef __cplusplus</tt> blocks, |
| but we are not convinced that is always going to work (some compilers have |
| weird interactions between comment stripping and pre-processing), and it |
| hardly seems worth the effort. Just stick to C style <tt>/**/</tt> comments |
| for any header file that is ever likely to be included by a C file. |
| <h2><a NAME="put_new_line_at_eof"></a>Put a new line at end-of-file.</h2> |
| <p>Not having a new-line char at end-of-file breaks some compilers (Solaris). |
| <h2><a NAME="no_extra_semi_colons"></a>Don't put extra top-level semi-colons |
| in code.</h2> |
| <p>Non-portable example: |
| <pre> |
| int |
| A::foo() |
| { |
| }; |
| </pre> |
| This is another problem that seems to show up more on C++ than C code. |
| This is problem really a bit of a drag. That extra little semi-colon at |
| the end of the function is ignored by most compilers, but it makes some |
| compilers very unhappy (IBM's AIX compiler doesn't like extra top-level |
| semi-colons). Don't do it. |
| <p>Portable example: |
| <pre> |
| int |
| A::foo() |
| { |
| } |
| </pre> |
| <h2><a NAME="file_extension_is_cpp"></a>C++ filename extension is <tt>.cxx</tt>.</h2> |
| <p>This one is another plain annoying problem. What's the name of a C++ |
| file? <tt>file.cpp</tt>, <tt>file.cc</tt>, <tt>file.C</tt>, <tt>file.cxx</tt>, |
| <tt>file.c++</tt>, |
| <tt>file.C++</tt>? |
| Most compilers could care less, but some are very particular. We have not |
| been able to find one file extension which we can use on all the platforms |
| we have ported OpenOffice.org code to. For no great reason, we've settled |
| on <tt>file.cxx</tt>, probably because the first C++ code in OpenOffice.org |
| code was checked in with that extension. Well, it's done. The extension |
| we use is <tt>.cxx</tt>. This extension seems to make most compilers happy, |
| but there are some which do not like it. |
| <h2><a NAME="dont_use_init_lists_with_cpp"></a>Don't use initializer |
| lists with objects.</h2> |
| <p>Non-portable example: |
| <pre STYLE="margin-bottom: 0.2in"> FooClass myFoo = {10, 20};</pre> |
| Some compilers won't allow this syntax for objects (HP-UX won't), actually |
| only some will allow it. So don't do it. Again, use a wrapper function, |
| see <a href="http://www.mozilla.org/hacking/portable-cpp.html#dont_use_static_constructors">Don't |
| use static constructors.</a> |
| <h2><a NAME="always_have_default_constructor"></a>Always have a default |
| constructor.</h2> |
| <p>Always have a default constructor, even if it doesn't make sense in |
| terms of the object structure/hierarchy. HP-UX will barf on statically |
| initialized objects that don't have default constructors. |
| <h2><a NAME="inner_classes"></a>Be careful with inner-classes.</h2> |
| <p>Some compilers (HP-UX) generally require that types (classes, enums, |
| etc.) declared inside of another class should be referred to with their |
| fully scoped form (e.g., <tt>Foo::kListMaxLen</tt> versus <tt>kListMaxLen</tt>). |
| <h2><a NAME="init_variables_at_top"></a>Be careful of variable declarations |
| that require construction or initialization.</h2> |
| <p>Non-portable example: |
| <pre> |
| void |
| A::foo(int c) |
| { |
| switch(c) { |
| case FOOBAR_1: |
| XyzClass buf(100); |
| // <i>stuff |
| </i> break; |
| } |
| } |
| </pre> |
| Be careful with variable placement around if blocks and switch statements. |
| Some compilers (HP-UX) require that any variable requiring a constructor/initializer |
| to be run, needs to be at the start of the method -- it won't compile code |
| when a variable is declared inside a switch statement and needs a default |
| constructor to run. |
| <p>Portable example: |
| <pre> |
| void |
| A::foo(int c) |
| { |
| XyzClass buf(100); |
| |
| switch(c) { |
| case FOOBAR_1: |
| // <i>stuff</i> |
| break; |
| } |
| } |
| </pre> |
| <h2><a NAME="header_files_c_and_cpp"></a>Make header files compatible with |
| C and C++.</h2> |
| <p>Non-portable example: |
| <pre> |
| /*<i>oldCheader.h</i>*/ |
| int existingCfunction(char*); |
| int anotherExistingCfunction(char*); |
| |
| /*<i> oldCfile.c </i>*/ |
| #include "oldCheader.h" |
| ... |
| |
| // <i>new file.cxx</i> |
| extern "C" { |
| #include "oldCheader.h" |
| }; |
| ... |
| </pre> |
| If you make new header files with exposed C interfaces, make the header |
| files work correctly when they are included by both C and C++ files. If |
| you start including an existing C header in new C++ files, fix the C header |
| file to support C++ (as well as C), don't just <tt>extern "C" {}</tt> the |
| old header file. Do this: |
| <p>Portable example: |
| <pre> |
| /*<i>oldCheader.h</i>*/ |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| int existingCfunction(char*); |
| int anotherExistingCfunction(char*); |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| /*<i> oldCfile.c </i>*/ |
| #include "oldCheader.h" |
| ... |
| |
| // <i>new file.cxx</i> |
| #include "oldCheader.h" |
| ... |
| </pre> |
| There are number of reasons for doing this, other than just good style. |
| For one thing, you are making life easier for everyone else, doing the |
| work in one common place (the header file) instead of all the C++ files |
| that include it. Also, by making the C header safe for C++, you document |
| that "hey, this file is now being included in C++". That's a good thing. |
| You also avoid a big portability nightmare that is nasty to fix... |
| <p>Some systems include C++ in system header files that are designed to |
| be included by C or C++. Not just <tt>extern "C" {}</tt> guarding, but |
| actual C++ code, usually in the form of inline functions that serve as |
| "optimizations". While we question the wisdom of vendors doing this, there |
| is nothing we can do about it. Changing system header files, is not a path |
| we wish to take. Anyway, so why is this a problem? Take for example the |
| following code fragment: |
| <p>Non-portable example: |
| <pre> |
| /*<i>system.h</i>*/ |
| #ifdef __cplusplus |
| /*<i> optimization </i>*/ |
| inline int sqr(int x) {return(x*x);} |
| #endif |
| |
| /*<i>header.h</i>*/ |
| #include <system.h> |
| int existingCfunction(char*); |
| |
| // <i>file.cxx </i> |
| extern "C" { |
| #include "header.h" |
| } |
| </pre> |
| What's going to happen? When the C++ compiler finds the <tt>extern "C"</tt> |
| declaration in <tt>file.cxx</tt>, it will switch dialects to C, because |
| it's assumed all the code inside is C code, and C's type free name rules |
| need to be applied. But the __cplusplus pre-processor macro is still defined |
| (that's seen by the pre-processor, not the compiler). In the system header |
| file the C++ code inside the <tt>#ifdef __cplusplus</tt> block will be |
| seen by the compiler (now running in C mode). Syntax Errors galore! If |
| instead the <tt>extern "C"</tt> was done in the header file, the C functions |
| can be correctly guarded, leaving the systems header file out of the equation. |
| This works: |
| <p>Portable example: |
| <pre> |
| /*<i>system.h</i>*/ |
| #ifdef __cplusplus |
| /*<i> optimization </i>*/ |
| inline int sqr(int x) {return(x*x);} |
| #endif |
| |
| /*<i>header.h</i>*/ |
| #include <system.h> |
| extern "C" { |
| int existingCfunction(char*); |
| } |
| |
| // <i>file.cxx</i> |
| #include "header.h" |
| </pre> |
| One more thing before we leave the <tt>extern "C"</tt> segment of the program. |
| Sometimes you're going to have to <tt>extern "C"</tt> system files. This |
| is because you need to include C system header files that do not have <tt>extern |
| "C"</tt> guarding themselves. Most vendors have updated all their headers |
| to support C++, but there are still a few out there that won't grok C++. |
| You might have to do this only for some platforms, not for others (using |
| <tt>#ifdef |
| SYSTEM_X</tt>). The safest place to do <tt>extern "C"</tt> a system header |
| file (in fact the safest place to include a system header file) is at the |
| lowest place possible in the header file inclusion hierarchy. That is, |
| push all this stuff down to the header files closer to the system code, |
| don't do this stuff in the mail header files. Ideally the best place to |
| do this is in the NSPR or XP header files - which sit directly on the system |
| code. |
| <h2><a NAME="variables_in_for"></a>Be careful of the scoping of variables |
| declared inside <tt>for()</tt> statements.</h2> |
| <p>Non-portable example: |
| <pre> |
| void |
| A::foo() |
| { |
| for (int i = 0; i < 10; i++) { |
| // <i>do something</i> |
| } |
| // <i><b>i</b> might get referenced</i> |
| // <i> after the loop.</i> |
| ... |
| } |
| </pre> |
| This is actually an issue that comes about because the C++ standard has |
| changed over time. The original C++ specification would scope the <b>i</b> |
| as part of the outer block (in this case function <tt>A::foo()</tt>). The |
| standard changed so that now the <b>i</b> in is scoped within the <tt>for() |
| {}</tt> block. Most compilers use the new standard. Some compilers (for |
| example, HP-UX) still use the old standard. Some other compilers (for example, |
| gcc) use the new rules, but will tolerate the old. If <b>i</b> was referenced |
| later in the <tt>for() {}</tt> block, gcc will allow the construct, but |
| give a warning about use of an "obsolete binding". So, while the code above |
| is valid, it would become ambiguous if <b>i</b> was used later in the function. |
| It's probably better to be on the safe side and declare the iterator variable |
| outside of the <tt>for()</tt> loop. Then you'll know what you are getting |
| on all platforms: |
| <p>Portable example: |
| <pre> |
| void |
| A::foo() |
| { |
| int i; |
| for (i = 0; i < 10; i++) { |
| // <i>do something</i> |
| } |
| // <i><b>i</b> might get referenced</i> |
| // <i> after the loop.</i> |
| ... |
| } |
| </pre> |
| <h2><a NAME="local_aggregates"></a>Declare local initialized aggregates |
| as static.</h2> |
| <p>Non-portable example: |
| <pre> |
| void |
| A:: func_foo() |
| { |
| char* foo_int[] = {"1", "2", "C"}; |
| ... |
| } |
| </pre> |
| This seemingly innocent piece of code will generate a "loader error" using |
| the HP-UX compiler/linker. If you really meant for the array to be static |
| data, say so: |
| <p>Portable example: |
| <pre> |
| void |
| A:: func_foo() |
| { |
| static char *foo_int[] = {"1", "2", "C"}; |
| ... |
| } |
| </pre> |
| Otherwise you can keep the array as an automatic, and initialize by hand: |
| <p>Portable example: |
| <pre> |
| void |
| A:: func_foo() |
| { |
| char *foo_int[3]; |
| |
| foo_int[0] = XP_STRDUP("1"); |
| foo_int[1] = XP_STRDUP("2"); |
| foo_int[2] = XP_STRDUP("C"); |
| // <i>or something equally Byzantine...</i> |
| ... |
| } |
| </pre> |
| <h2><a NAME="complex_inlines"></a>Expect complex inlines to be non-portable.</h2> |
| <p>Non-portable example: |
| <pre> |
| class FooClass { |
| ... |
| int fooMethod(char* p) { |
| if (p[0] == '\0') |
| return -1; |
| |
| doSomething(); |
| return 0; |
| } |
| ... |
| }; |
| </pre> |
| It's surprising, but many C++ compilers do a very bad job of handling inline |
| member functions. Cfront based compilers (like those on SCO and HP-UX) |
| are prone to give up on all but the most simple inline functions, with |
| the error message "sorry, unimplemented". Often times the source of this |
| problem is an inline with multiple return statements. The fix for this |
| is to resolve the returns into a single point at the end of the function. |
| But there are other constructs which will result in "not implemented". |
| For this reason, you'll see that most of the C++ code in Mozilla does not |
| use inline functions. We don't want to legislate inline functions away, |
| but you should be aware that there is some danger in using them, so do |
| so only when there is some measurable gain (not just a random hope of performance |
| win). <b>Maybe you should just not go there.</b> |
| <p>Portable example: |
| <pre> |
| class FooClass { |
| ... |
| int fooMethod(char* p) { |
| int return_value; |
| |
| if (p[0] == '\0') { |
| return_value = -1; |
| } else { |
| doSomething(); |
| return_value = 0; |
| } |
| return return_value; |
| } |
| ... |
| }; |
| </pre> |
| Or |
| <p>Portable example: |
| <pre> |
| class FooClass { |
| ... |
| int fooMethod(char* p); |
| ... |
| }; |
| |
| int FooClass::fooMethod(char* p) |
| { |
| if (p[0] == '\0') |
| return -1; |
| |
| doSomething(); |
| return 0; |
| } |
| </pre> |
| <h2><a NAME="inlines_in_return"></a>Don't use return statements that have |
| an inline function in the return expression.</h2> |
| <p>For the same reason as the previous tip, don't use return statements |
| that have an inline function in the return expression. You'll get that |
| same "sorry, unimplemented" error. Store the return value in a temporary, |
| then pass that back. |
| <h2><a NAME="virtual_on_subclasses"></a>Use virtual declaration on all |
| subclass virtual member functions.</h2> |
| <p>Non-portable example: |
| <pre> |
| class A { |
| virtual void foobar(char*); |
| }; |
| |
| class B : public A { |
| void foobar(char*); |
| }; |
| </pre> |
| Another drag. In the class declarations above, <tt>A::foobar()</tt> is |
| declared as virtual. C++ says that all implementations of void <tt>foobar(char*)</tt> |
| in subclasses will also be virtual (once virtual, always virtual). This |
| code is really fine, but some compilers want the virtual declaration also |
| used on overloaded functions of the virtual in subclasses. If you don't |
| do it, you get warnings. While this is not a hard error, because this stuff |
| tends to be in headers files, you'll get so many warnings that's you'll |
| go nuts. Better to silence the compiler warnings, by including the virtual |
| declaration in the subclasses. It's also better documentation: |
| <p>Portable example: |
| <pre> |
| class A { |
| virtual void foobar(char*); |
| }; |
| |
| class B : public A { |
| virtual void foobar(char*); |
| }; |
| </pre> |
| <h2><a NAME="copy_constructors"></a>Always declare a copy constructor and |
| assignment operator.</h2> |
| <p>One feature of C++ that can be problematic is the use of copy constructors. |
| Because a class's copy constructor defines what it means to pass and return |
| objects by value (or if you prefer, pass by value means call the copy constructor), |
| it's important to get this right. There are times when the compiler will |
| silently generate a call to a copy constructor, that maybe you do not want. |
| For example, when a you pass an object by value as a function parameter, |
| a temporary copy is made, which gets passed, then destroyed on return from |
| the function. Maybe you don't want this to happen, maybe you'd always like |
| instances of your class to be passed by reference. If you do not define |
| a copy constructor the C++ compiler will generate one for you (the default |
| copy constructor), and this automatically generated copy constructor might, |
| well, suck. So you have a situation where the compiler is going to silently |
| generate calls to a piece of code that might not be the greatest code for |
| the job (it may be wrong). |
| <p>Ok, you say, "no problem, I know when I'm calling the copy constructor, |
| and I know I'm not doing it". But what about other people using your class? |
| The safe bet is to do one of two things: if you want your class to support |
| pass by value, then write a good copy constructor for your class. If you |
| see no reason to support pass by value on your class, then you should explicitly |
| prohibit this, don't let the compiler's default copy constructor do it |
| for you. The way to enforce your policy is to declare the copy constructor |
| as private, and not supply a definition. While your at it, do the same |
| for the assignment operator used for assignment of objects of the same |
| class. Example: |
| <pre> |
| class foo { |
| ... |
| private: |
| // <i>These are not supported</i> |
| // <i>and are not implemented!</i> |
| foo(const foo& x); |
| foo& operator=(const foo& x); |
| }; |
| </pre> |
| When you do this, you ensure that code that implicitly calls the copy constructor |
| will not compile and link. That way nothing happens in the dark. When a |
| user's code won't compile, they'll see that they were passing by value, |
| when they meant to pass by reference (oops). |
| <h2><a NAME="signatures"></a>Be careful of overloaded methods with like |
| signatures.</h2> |
| <p>It's best to avoid overloading methods when the type signature of the |
| methods differs only by 1 "abstract" type (e.g. <tt>PR_Int32</tt> or <tt>int32</tt>). |
| What you will find as you move that code to different platforms, is suddenly |
| on the Foo2000 compiler your overloaded methods will have the same type-signature. |
| <h2><a NAME="type_scalar_constants"></a>Type scalar constants to avoid |
| unexpected ambiguities.</h2> |
| <p>Non-portable code: |
| <pre> |
| class FooClass { |
| // <i>having such similar signatures</i> |
| // <i>is a bad idea in the first place.</i> |
| void doit(long); |
| void doit(short); |
| }; |
| |
| void |
| B::foo(FooClass* xyz) |
| { |
| xyz->doit(45); |
| } |
| </pre> |
| Be sure to type your scalar constants, e.g., PR_INT32(10) or 10L. Otherwise, |
| you can produce ambiguous function calls which potentially could resolve |
| to multiple methods, particularly if you haven't followed (2) above. Not |
| all of the compilers will flag ambiguous method calls. |
| <p>Portable code: |
| <pre> |
| class FooClass { |
| // <i>having such similar signatures</i> |
| // <i>is a bad idea in the first place.</i> |
| void doit(long); |
| void doit(short); |
| }; |
| |
| void |
| B::foo(FooClass* xyz) |
| { |
| xyz->doit(45L); |
| } |
| </pre> |
| <h2><a NAME="bool_types"></a>Type scalar constants to avoid unexpected ambiguities.</h2> |
| <p>Some platforms (e.g. Linux) have native definitions of types like bool |
| which sometimes conflict with definitions OpenOffice.org code. Always use |
| sal_Bool.. |
| |
| <h1><a NAME="c_and_cplusplus"></a>Stuff that is good to do for C or C++.</h1> |
| |
| <h2><a NAME="dont_ifdef_include"></a>Do not wrap include statements |
| with an <tt>#ifdef</tt>.</h2> |
| <p>Do not wrap include statements with an <tt>#ifdef</tt>. The reason is |
| that when the symbol is not defined, other compiler symbols will not be |
| defined and it will be hard to test the code on all platforms. An example |
| of what not to do: |
| <p>Bad code example: |
| <pre> |
| // don't do this |
| #ifdef X |
| #include "foo.h" |
| #endif |
| </pre> |
| The exception to this rule is when you are including different system files |
| for different machines. In that case, you may need to have a <tt>#ifdef |
| SYSTEM_X</tt> include. |
| <h2><a NAME="assignments_in_boolean"></a>Macs complain about assignments |
| in boolean expressions.</h2> |
| <p>Another example of code that will generate warnings on a Mac: |
| <p>Generates warnings code: |
| <pre STYLE="margin-bottom: 0.2in"> if ((a = b) == c) ...</pre> |
| Macs don't like assignments in <b>if</b> statements, even if you properly |
| wrap them in parentheses. |
| <p>More portable example: |
| <pre> |
| a=b; |
| if (a == c) ... |
| </pre> |
| <h2><a NAME="filenames_must_be_unique"></a>Every source file must have a |
| unique name.</h2> |
| <p>Non-portable file tree: |
| <pre> |
| feature_x |
| private.h |
| x.cxx |
| feature_y |
| private.h |
| y.cxx |
| </pre> |
| For Mac compilers, every has to have a unique name. Don't assume that just |
| because your file is only used locally that it's OK to use the same name |
| as a header file elsewhere. It's not ok. Every filename must be different. |
| <p>Portable file tree: |
| <pre> |
| feature_x |
| xprivate.h |
| x.cxx |
| feature_y |
| yprivate.h |
| y.cxx |
| </pre> |
| <b>Use <tt>#if 0</tt> rather than comments to temporarily kill blocks of |
| code.</b> |
| <p>Non-portable example: |
| <pre> |
| int |
| foo() |
| { |
| ... |
| a = b + c; |
| /* |
| * Not doing this right now. |
| a += 87; |
| if (a > b) (* have to check for the |
| candy factor *) |
| c++; |
| */ |
| ... |
| } |
| </pre> |
| This is a bad idea, because you always end up wanting to kill code blocks |
| that include comments already. No, you can't rely on comments nesting properly. |
| That's far from portable. You have to do something crazy like changing |
| <tt>/**/</tt> |
| pairs to <tt>(**)</tt> pairs. You'll forget. And don't try using <tt>#ifdef |
| NOTUSED</tt>, the day you do that, the next day someone will quietly start |
| defining <tt>NOTUSED</tt> somewhere. It's much better to block the code |
| out with a <tt>#if 0</tt>, <tt>#endif</tt> pair, and a good comment at |
| the top. Of course, this kind of thing should always be a temporary thing, |
| unless the blocked out code fulfills some amazing documentation purpose. |
| <p>Portable example: |
| <pre> |
| int |
| foo() |
| { |
| ... |
| a = b + c; |
| #if 0 |
| /*<i> Not doing this right now. </i>*/ |
| a += 87; |
| if (a > b) /*<i> have to check for the |
| candy factor </i>*/ |
| c++; |
| #endif |
| ... |
| } |
| </pre> |
| <h2>Source code formatting.</h2> |
| <p>After some discussion we agreed that basic indentation should be four |
| spaces, no tabs. Please use an editor setting which expands a typed tab |
| into spaces. Some examples:</p><br> |
| <code>vim: set expandtab</code><br> |
| <code>emacs: (setq-default indent-tabs-mode nil)</code><br> |
| <code>msdev: check Options->Tabs->Insert Spaces</code><br> |
| </td> |
| </tr> |
| </table> |
| </body> |
| </html> |