:toc:

== Introduction

Open Watcom products are usually written mostly in C, but there is also
a substantial body of {cpp} code and a small amount of assembler for
various platforms. This document describes the style conventions used by
Open Watcom contributors for all Open Watcom projects, and is intended to
be used as a guideline if you are going to be modifying the source code
in any way. Any contributed code that is to be included in a Open Watcom
product must follow these style guidelines; submissions violating these
guidelines will be rejected.

It is important to have all source code formatted in a similar manner as
this helps to give the entire product a cohesive image, and makes
finding one's way around the source code much easier. Because C and {cpp}
are entirely free-form, there are many different ways that the source
code can be formatted. All programmers have their own preferred
formatting style, just as all writers have their own personal writing
style. However, just as when multiple authors work on a single book,
multiple programmers working on a common software product should adhere
to consistent formatting and style conventions.

This document is intended to serve as a guide to the style guidelines
used by Open Watcom developers. If, however, something is not clearly
documented here, the best reference to the style guidelines is to look
at some Open Watcom source code.

NB: The Open Watcom code base is very large (over two million lines of
C/{cpp} source code) and was written by many people over the period of
over 20 years. As a result, not every source file conforms to these
guidelines. You may wish to reformat existing non-conforming source
files, but if you do so, please observe the following: it is highly
recommended that you reformat an entire project or subproject instead of
a single source file, and never mix formatting changes with functional
changes. Always submit formatting changes separately, as it makes source
code maintenance much easier.

== Indentation and Tab Width

All source code should be formatted to use 4-space tabs, and all
indentation should be in multiples of four spaces (one indentation level).
The source code should be formatted using only real spaces and never
hard tabs, so you will need to configure your editor to use 4 space tabs
and to insert spaces only into the source code. Do NOT use 8-space hard
tabs in your source code! If you absolutely must work with 8-space hard
tabs, please run the resulting source code through a tab expansion
utility. Note that this also includes assembly code. Only files that
absolutely require hard tabs (notably GNU makefiles) are exempt from
this rule.

== Source Code Width

All source code should try to use a maximum of 80 characters per line.
Some editors can only display 80 characters on a line, and using more
can cause them to exhibit line wrap. This is only a guideline, and if
more than 80 characters will enhance the legibility of the code, use
wider source lines---but not too much wider. Lines longer than 100
characters are suspect and more than 130 columns is absolutely out of
the question.

== C/{cpp} Source Code Formatting

This section describes the conventions used for formatting C and {cpp}
source code modules, and the conventions that you should follow if you
modify or extend any of the source code. All C source code should be
contained in text files with the .c extension, and all {cpp} source code
should be contained in text files with the .cpp extension. It is highly
recommended that all source file names are lowercase and following the
8.3 convention for maximum portability. Files that are not lowercase
are only acceptable if there are externally imposed requirements for
them; it is never allowed to have two files in the same directory whose
names only differ in case.

== Source File Layout

The overall layout for source code is important to help developers
quickly find their way around unfamiliar source code for the first time.
All C and {cpp} source code modules should be formatted in the following
manner:

----
/****************************************************************************
*
*                            Open Watcom Project
*
* Copyright (c) 2002-2019 The Open Watcom Contributors. All Rights Reserved.
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Description of the code module. This should describe the
*               purpose of the code in this module.
*
****************************************************************************/


#include "myhdr.h"      /* Include any necessary headers */

/* Global variable declarations and static variables with file scope */

/* All functions implemented in this module. Where possible static or
 * private functions should be located before functions that use them to
 * avoid the need for superfluous function prototypes. However all functions
 * *MUST* have a prototype, so if necessary add local prototypes to the top
 * of the file before the regular functions begin.
 */
----

=== Function Body

The body of a C or {cpp} function should be written with the open brace
that starts the body of the function in the leftmost column, and the
closing brace in the same column. All source code statements contained
within the function body should start at the first indentation level (four
spaces in). The name of the function and an opening '(' should be on the
first line, with the return type preceding the function name.

If the function is static or private, it may be left without any
preceding documenation provided the function is short. However any
function that contains more than about 5 lines of source code and all
public functions should be preceded with a source code comment. An
example of a properly formatted function with documentation header is as
follows:

----
// Concise description of the function.
// May use C or C++ style comments.
bool my_function( int arg1, int arg2 )
{
    // function body
}
----

There is no single standard for commenting functions used throughout the Open Watcom source tree.  However, two common commenting styles are shown below:

----
/*
 * my_function - description of the my_function function, which may span
 *               multiple lines if necessary
 */
bool my_function( int arg1, int arg2 )
{
    // function body

} /* my_function */
----

----
bool my_function( int arg1, int arg2 )
/************************************/
{
    // function body
}
----

Generally, it is a good idea to use the same commenting style throughout
any particular module.

If a function has too many arguments to comfortably fit on a single line,
the line needs to be broken up appropriately. Recommended formatting is
as follows:

----
void my_long_function( first_complex_type *arg1, second_complex_type *arg2,
                       int arg3, third_complex_type *arg4 )
{
    // function body goes here
}
----

Note that a C language function which takes no parameters should be
declared as `type foo( void )` rather than `type foo()`.
The former says `foo` has no parameters; the latter that parameters
are unspecified.
When declaring a {cpp} function that takes no arguments or calling a function in C/{cpp} with no arguments there should be no space between the parenthesis `()`.

Several projects in the source tree use capitalisation rather than underscores to separate the words.  Continuity within a project is important.  In this case the first word is not capitalised for a function local to that module and is capitalised for an exteral function.

----
void MyFunction( void );  // external to module
void myFunction( void );  // local to module
----

=== Flow Control Statements

All the flow control statements should have the open brace placed on the
same line as the start of the flow control statements, and all
statements that are part of the body of the flow control statement
should be indented by one level (four spaces). The closing brace should be
indented to be at the same level as the flow control statement keyword.
This helps to partition the statement into the declaration section and
the body section of the statement. Note also that for improved legibility,
the flow control statements should be formatted with a single space after
the opening parenthesis and another before the closeing parenthesis, as well
as a space before the opening brace. For example:

----
if( condition ) {
}
----

rather than the less legible

----
if(condition){
}
----

Where the dependent statement does not require braces, it may be, in order
of preference, either:

* be given braces it does not strictly require
----
if( condition ) {
    consequence;
}
----

* indented on the next line
----
if( condition )
    consequence;
----

* placed on the same line
----
if( condition ) consequence;
----

The last form is not recommended for practical reasons. If a conditional
statement is formated like

----
if( condition ) do_something();
----

it is not immediately obvious when stepping over the line in a debugger
whether `do_something()` was executed or not. Hence if this form
is used, it should only ever be done with control constructs such as
`return`, `break` or `continue`. Even so,
it is impossible to put a breakpoint on the conditional statement in a line
oriented debugger, therefore this form should be avoided.

The following shows the templates to use for formatting each of the flow
control structures in C and {cpp}.

=== If-else Statements

----
if( x < foo ) {
    // do something;
} else {
    // do something else;
}
----

If you wish to use multiple if-else statements strung together, do so
like this:

----
if( x < foo ) {
    // do something;
} else if( x < bar ) {
    // do something else;
} else {
    // default case;
}
----

When you have an if-else statement nested in another if-else statement,
put braces around the nested if-else. For example:

----
if( foo ) {
    if( bar ) {
        win();
    } else {
        lose();
    }
}
----

rather than the less legible:

----
if( foo )
    if( bar )
        win();
    else
        lose();
----

=== While Loops

----
while( x > 1 ) {
    // do something;
}
----

=== Do-while Loops

----
do {
    // do something;
} while( x > 1 );
----

=== For Loops

----
for( i = 0; i < 10; ++i ) {
    // do something;
}
----

Note that with the for statement, there is no space before the
semicolons, and there is always a single space after the semicolon. For
example avoid formatting your statements like this:

----
for(i=0;i<10;i++){
}
----

If you wish to include multiple assignments in the opening statement
of the for statement, or multiple operations in the counter
section of the for statement then use the comma operator. However ensure
that a space always follows the comma:

----
for( i = 0, j = 0; i < 10; ++i, j += 10 ) {
}
----

Do not try to cram too much into the controlling statement of the for loop.
For instance the following code (not a contrived example, unfortunately) is not
admissible under any circumstances and may be considered a capital offence in
some countries:
----
for(RamAddr=_uldiv(__nvram.CMapShadow.CMapTable[pIO->Selector].Offset+
    pIO->Offset,__nvram.WinSize),Copied=0U,pApp=(PBYTE)pIO->Data;
    Copy=(USHORT)min(__nvram.WinSize-RamAddr.rem,(ULONG)pIO->Size);
    pIO->Size-=Copy,Copied+=Copy,RamAddr.quot++,RamAddr.rem=0UL,
    pApp=pApp+Copy)
    {
        /* loop body */
    }
----
The rule of thumb is that if the controlling statement of a for loop is
longer than a single line, it is too long.

----
for( ;; ) {
    // do something;
}
----

should be used instead of the alternative

----
while( 1 ) {
    // do something in a not so nice way;
}
----

The rationale is that some compilers may warn on the latter form because the
condition is always true.

=== Switch Statements

----
switch( x ) {
case 1:
    // code for case 1
    break;
case 2:
    // code for case 2
    break;
default:
    // default case
}
----

`case` and `default` are viewed as part of
`switch` for indentation purposes.

If the code for the cases in the `switch` statement is
exceptionally short, you can format the entire case on a single line,
such as the following:

----
switch( x ) {
case 1: /* tiny code */;   break;
case 2: /* more code */;   break;
}
----

If you wish to create a nested code block for a `case` statement
(for example to declare some local variables in C code), do so like the
following:

----
switch( x ) {
case 1:
    {
        int local_var;
        // code for case 1
    }
    break;
    ...
}
----

It is advisable to include a default action for a switch statement, but
this may be left out.

If falling through is used in `switch` statements, a comment to
that effect must be added, such as this:

----
switch( x ) {
case 1:
    // code for case 1
/* fall through */
case 2;
    // code for case 2
    break;
default:
    // default case
}
----

=== Goto Statements

Occasionally, it is reasonable to use `goto`
statements. The corresponding labels should be indented to the same level
as the braces enclosing both goto and label.

----
switch( argv[0][1] ) {
...
case 'D':
    if( !optionsPredefine( &argv[0][2] ) )
        goto errInvalid;
    break;
...
default:
errInvalid:
...
}
----

Usage of gotos should be kept to minimum and is generally not recommended,
although the objections are purely practical (difficult to understand and
maintain, dangerous) and not religious.

=== Expressions

When formatting expressions, try to use spaces and parentheses to
enhance the readability of the expression---splitting it over multiple
lines if necessary to make it more readable. Do not format expressions
without any spaces between binary operators and their operands. For
example, write

    x = (y + 10) - 240 * (20 / (t + my_func()));

rather than

    x=(y+10)-240*(20/(t+my_func()));

If parentheses contain an expression, there should be no space
after the opening and before the closing parenthesis. Combined with the
preceding guidelines, code should be formatted this way:

----
if( (a || my_func( b )) && ((c = my_other_func( 1 + x )) == 42) ) {
    // do something
}
----

That is, for parentheses that are parts of control statements and function
calls, spaces should be after the opening and before the closing parenthesis,
but spaces need not be used with parentheses that simply group expressions
together.

The parentheses following the `TEXT` and `_T` prefixes commonly used to specify strings in Win32 code should be considered to be instances of this rule and should not have spaces around the string, even though these prefixes are implemented as macros.  For example, write

----
const TCHAR szString[] = _T("Some Text");
----

=== Return Statements

In functions that return a value, the return expression should be placed
in parentheses. For example:

    return( i + 1 );

or

    return( TRUE );

In other words, format return statements as if `return` was a
function.

=== Operator sizeof

The same applies to the `sizeof` operator, that is, parentheses
should always be used as if `sizeof` was a function (which it
of course isn't). For example:

    i = sizeof( void * );

=== Variable Declarations

Don't declare multiple variables in one declaration that spans lines.
Instead, start a new declaration on each line. For example, instead of

----
    int foo,
        bar;
----

write either this (recommended form):

----
    int foo;
    int bar;
----

or, if you are lazy, this:

----
    int foo, bar;
----

=== Global Variables Within a Module

Any global variables and external global variables must be declared at
the top of the source file. Global variables that are private to the
source module should always be declared with `static` storage.
External global variables should always be declared in a separate header
file, and the definition in a single source module. When formatting
global variables, aligning the names of the variables on tab stops is
highly recommended. For example:

----
// 45678 1 234567  column counter for illustration.
int         my_var1;
long        my_var2;
my_struct   my_structure = {
    ...
};
----

=== Local Variables

Declarations of local variables should be formatted similarly to those
of global variables, as detailed above. For example:

----
void foo( void )
// 45678 1 234567  column counter for illustration.
{
    int         my_var1;
    long        my_var2;
    void const  *my_ptr;

    // code follows here
}
----

Note that the declaration block is separated from the first statement in
the function by a blank line. The `register` storage class
specifier should not be used because nearly all compilers will ignore it,
and the `auto` storage class should not be used either as it
is superfluous in the presence of a type specifier (which is required by
ISO C99, although it was not in earlier language revisions).

=== Arrays

When an array is dimensioned or accessed, the subscript should be specified with no space to the right of the left square bracket or to the left of the right square bracket. For example:

----
int array[5];
do_something( array[3] );
----

=== Preprocessor Directives

When a series of preprocessor directives (`#define`, `#include`, etc.) is conditionally processed, the directives between `#if` or `#ifdef` and the corresponding `#endif` should be indented four or two spaces. For example:

----
#ifdef A_SYMBOL
    #ifdef ANOTHER_SYMBOL
        #define YET_ANOTHER_SYMBOL
        #include <hdr1.h>
    #endif
    #ifdef A_THIRD_SYMBOL
        #include <hdr2.h>
    #else
        #include <hdr3.h>
        #undef A_SYMBOL
    #endif
#endif
----

The above only applies for source text that consists solely or chiefly of preprocessor directives. When conditional compilation is used to prevent duplicate inclusion of an entire header file (idempotency lock), the code in that header file should not be automatically indented. Also, when `extern "C" {` and `}` are placed in `#ifdef __cplusplus` blocks, they need not be indented.

For conditional compilation of code, the rules are somewhat different. In most cases, preprocessing directives should start at the leftmost column and should not affect the indentation of actual code. For example:

----
void foo( int b )
{
    if( b > 3 ) {
        do_stuff();
#ifdef __NT__
        do_nt_stuff();
#elif defined( __OS2__ )
        do_os2_stuff();
#endif
        do_more_stuff();
    } else {
        do_something_else();
    }
}
----

=== Comments and Commenting Style

Commenting code is extremely important. Comments serve as an aid to the
human readers of source code; they are a form of engineering etiquette.
Comments should always be used to clarify otherwise obscure code.
Do not, however, comment too liberally. If the code itself describes
concisely what is happening, do NOT provide a comment explaining the
obvious! Comments should always be neat and readable - haphazardly
placed comments are almost as bad as haphazardly formatted source code.

Comments should also be used to document the purpose of obscure or
non-trivial functions (a non-trivial function is one of more than a few
lines) and what inputs and outputs the function deals with. Please refer
to the section on Function Bodies for detailed information on the layout
and formatting for function headers. The following shows examples for
commented source code, and how the comments should be laid out:

----
void myFunc( void )
{
    int x1 = 10;    /* Comment describing X1's purpose if necessary */

    /* Open up the file and write the value X1 to it */
    ...

    /* Now do some stuff that is complicated, so we have a large block
     * comment that spans multiple lines. These should be formatted as
     * follows for C and C++ code.
     */
    ...

    // One line comments may be like this
    ...

    // C++ style comments are also allowed, but be aware that not all
    // C compilers may accept them; this could be an issue when porting
    // to new platforms.
    ...
----

== C Header File Formatting

This section describes the conventions used for formatting C header
files, and the conventions that you should follow if you modify or
extend any of the source code. All C header files should be contained in a text file with the .h extension. Note that automatically generated
header files usually use a .gh extension, but those files are naturally
not intended to be edited directly.

=== Header File Layout

The overall layout for header files is important to help developers
quickly find their way around unfamiliar source code for the first time.
All C header files should be formatted in the following manner:

----
/****************************************************************************
*
*                            Open Watcom Project
*
* Copyright (c) 2002-2019 The Open Watcom Contributors. All Rights Reserved.
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Description of the header file. This should describe the
*               purpose of this header file.
*
****************************************************************************/


#ifndef HEADER_H_INCLUDED   /* Include guard. The #define name should be   */
#define HEADER_H_INCLUDED   /* the same as the header (ie: header.h here). */
/* HEADER_H_INCLUDED would be in the user's "namespace". Implementation specific
 * headers distributed to end-users have to use reserved names, e.g.
 * #ifndef _STDLIB_H_INCLUDED
 * #define _STDLIB_H_INCLUDED
 * ...
 * #endif
 * Only system headers (ie. headers not intended to be built with any other
 * compiler) should use reserved names.
 */

#include <stdio.h>      /* Include any dependent include files */

/* If necessary, declare structure packing; The _Packed keyword may be
 * used on individual basis instead of the #pragma.
 */
#pragma pack( push, 1 )

/* Macros, enumerations, type definitions, structures and unions should be
 * defined in this section for both C and C++ code.
 */

/* Restore the previous packing value if it has been changed */
#pragma pack( pop )

/* The following is not stricly required for header files that are
 * never to be included from C++ code.
 */
#ifdef  __cplusplus
extern "C" {            /* Use "C" linkage when in C++ mode */
#endif

/* Include C function prototypes in here */

#ifdef  __cplusplus
}                       /* End of "C" linkage for C++ */
#endif

#endif  /* HEADER_H_INCLUDED */
----

=== Enumerations

Enumerations should be defined for all numerical constants used in
header files, rather than using a macro `#define` or a set of
constants. The reason for this is that it provides a logical grouping for
related constants, and perhaps more importantly, eases debugging (because
the debugger knows about enumerations but doesn't know about macros). The
format for defining an enumeration `typedef` is as follows:

----
typedef enum {
    CHANGE_NORMAL   = 0x00,
    CHANGE_ALL      = 0x01,
    CHANGE_GEN      = 0x02,
    CHANGE_CHECK    = 0x04
} change_type;
----

== Structures and Unions

It is preferred to declare structures and unions using a `typedef`,
so that the structure can be used without requiring the `struct` or
`union` keyword. For example:

----
typedef struct {
    ...
} score_reg;

typedef union {
    ...
} symbol;
----

rather than:

----
struct score_reg {
};

union symbol {
};
----

For {cpp} code however, you should declare structures and unions without
using the `typedef` keyword, since the language treats these
constructs differently.

=== Function Prototypes

All public functions must be declared in only one header file, in the
'function prototypes' section of the header file. For C callable
functions (even if implemented in {cpp}) the function prototypes must be
bracketed with `extern "C"` as shown in the sample header
file above. This is to ensure that all global functions will be callable
from both C and {cpp} code. Each public function should be declared on a
single line.

Although it may seem strange to format functions prototypes in this
manner, the C/{cpp} compiler will do the necessary job of checking that
the parameters in the prototype are correct with respect to the function
body, and having a single function per line makes it easy to browse
header files to find a specific function prototype. Note also that this
is one case where you must violate the 80 characters per line guideline
and not break the function prototype across multiple lines. For instance
a couple of prototypes might be declared as follows:

----
extern bool          my_function( int arg1, int arg2 );
extern my_structure *my_function2( int arg1, int arg2, int arg3 );
----

=== Global Variables

Any public global variables must be declared in a header file. When
formatting global variable declarations, format them so that the names
of the variables align on tab stops. For example:

----
// 45678 1 2345678 2 2345678
extern int          my_var1;
extern ulong        my_var2;
extern score_reg    my_structure;
extern long         *my_pointer;
----

== {cpp} Specific Formatting
This is WIP. Various bits will need to be filled in as we come to a consensus.

=== Header File Layout
TBD - just same layout as <<C Header File Formatting,Header File Layout>>?

=== Namespaces
* Always comment the close of a namespace
* Indentation TBD
* Standard names used for OW extentions and OW internals TBD

----
namespace std{
} // namespace std
----

=== Classes
TBD - should non-standard classes be written TheClass or the_class?

TBD - ditto for member functions?

Blocks of related member fuctions, typedefs, etc should have their names aligned so differences and simiularities can be seen more easily.

For small inline functions, place the function body within the class declaration. For inline
functions that are more than about 2 lines long, please place the body of the function after the class definition in the same header file.

Generally try to place a single class definition into a single header file. It may be more convenient in some instances to place multiple class definitions into a single header file, for example, small, logically related classes such as a node class and the list class that
uses the nodes.

The class should be ordered TBD.
If it defined by a standard it should follow the ordering in the standard as closely as posible.

----
class MyClass : public Base {
protected:
    int myVar;              // Describe what this is for

    // Comment for the function
    virtual void myProtectedFunction();

public:
    // constructors and destructor first
    MyClass();
    ~MyClass();

    // align related funtions to highlight differences and simularities
    void        insert( int value, int n );
    long_type   insert( const char *str, int n );
    bool        remove( int value );

    iterator        begin();
    const_iterator  begin() const;
    iterator        end();
    const_iterator  end() const;

    // Always document virtual functions
    virtual void myPublicVirtual();
    friend  void myPublicFriend();

    inline void smallInlineFunction() { // function body; };

    inline void mediumInlineFunction()
        { // function body; };

    inline void largeInlineFunction()
        {
            // first line of function
            // second line of function
        };

    inline void reallLargeInlineFunction();
    // body is defined outside of class
};
----

=== Templates

The parameter list for a template should be formatted, if possible, entirely on a single line. It is recommended that a space be placed immediately after the opening '<' and immediately before the closing '>'. This makes it less likely that the unexpected tokens will be produced (particularly '>>' or '<:'). It is also consistent with the way functions are formatted according to this guide.

----
template< class T, class U >
class MyClass {
    ...
};
----

Usually template functions and member function definitions should be formated simularly to normal functions:

----
template< class Type, class Allocator >
void list< Type, Allocator >::swap( list &other )
{
    ....
}

template< class InputIterator, class Function >
Function for_each( InputIterator first, InputIterator last, Function f )
{
    ...
}
----

It is probably best to avoid unnecessarily long parameter names but if the list is long a split will be necessary. Return types can get very long and in this case should be put on a separate line. An example is shown below.

----
template< class T,
          class ALongTypeParameter,
          class S,
          class AnotherType = WithDefault< T > >
complicated_template< T, ALongTypeParameter, S, AnotherType >::return_type
complicated_template< T, ALongTypeParameter, S, AnotherType >::function(
    const int i,
    size_type pos,
    S &s,
    const AnotherType &a )
{
    ...
}
----


=== Function Headers

In my opinion there is a need for some sort of function header comment. This is mainly due to the amount of time needed to read some {cpp} template member functions.

----
TBD put example of it here
----

== Recommended Practice and Pitfalls

This section details recommended programming practice as well as some
common pitfalls and gotchas. Following these suggestions is quite likely
to save programmers much time and frustration.

=== Don't Assume

Don't make too many assumptions about the language or environment. If,
say, ISO C does not specify something, do not rely on any particular
implementation. This includes, but is not limited to, type sizes, char
signedness, structure alignment, enumeration sizes, byte order, and
many, many other items. Some of these are discussed in greater detail
below.

=== Adherence to Standards

Programs should be written to comply with the most general standard
that provides desired functionality. For instance, on the Win32
platforms, there are three file I/O models available:

* Standard C library streams
* POSIX style file handle based I/O
* Win32 API calls

For most purposes, ISO C library stream functions are sufficient and
perform very well, therefore should be used. Only if a feature not
provided by the ISO C library is required, or the library for some
reason cannot be used, either POSIX or Win32 file I/O (in that order)
should be used.

In general, ISO C should be used wherever possible. Portable POSIX
interfaces should be used where ISO C is insufficient (and to the extent
that the POSIX functionality is supported by Open Watcom on all platforms).
Platform specific APIs should only be used as a last resort.

=== Compiler Warnings

Nearly all of the Open Watcom subprojects are set up to build with
maximum warnings and treat warnings as errors. That is a defence against
programmers trying to write sloppy code. Reducing the warning level is
out of the question and explicitly disabling warnings is frowned upon.
Nearly always there is a way to write code so that no warnings are
reported. In the extremely rare cases where that might not be possible,
a discussion about the usefulness of such warning is warranted.

=== Compiler Extensions

In general, code should be written with minimal reliance on compiler extensions
as long as it is intended to be portable. This means that for instance the
C compiler itself should be written in a portable manner, but eg. the
DOS specific portions of the runtime library need not be. In some cases (eg. the
Win386 extender) no other compiler comes close in capabilities and Open
Watcom specific extensions may be used freely -- simply because there is no danger
of porting that code to any other compiler or platform.

In cases where the use of an extension (such as `#pragma aux`) can
substantially improve otherwise portable code, it can be used, but an alternate
codepath needs to be provided for other compilers and/or platforms.

=== Type Selection

There is an art to selecting basic types in C and {cpp}. For writing portable
code, there are two simple rules:

* use specific width types if required
* use generic types in all other cases

That is, if specific types are imposed by file formats, networking protocols,
or hardware, always use types with explicitly specified width. The C99 types
such as `uint32_t`, `int16_t`, etc. are recommended.
Never ever assume that `int` or `long` has specific
width.

However, in other cases, select a suitable type sufficient to hold the range
of expected values, usually `int` or `long`.

Also do not assume that pointers have specific width. Use the C99
`uintptr_t` or `intptr_t` types if you need to convert
between integers and pointers.

In general, do use types designed for specific applications, such as
`size_t`, `off_t`, `pid_t`, etc.

=== Types and Conversions

Programmers need to have a good understanding of the C type system. That is
the only way to ensure that the type system will work for you, not against you.

Keep in mind that a constant such as 123 will have type `int`, which
has different size on different platforms. Constructs such as

    long l = 1024 * 1024;

may not do what you expect and explicit L suffix is necessary. Same goes for
arithmetic involving variables - explicit casts may be required to achieve
desired results.

On the other hand, casts should not be used indiscriminately as they tend
to obscure the purpose of code. Only use explicit casts where the default
conversions don't do the job.

Be extremely careful with functions that take variable number of arguments.
Keep in mind that default promotions will be applied to the variadic arguments.

=== Use of 'const'

Use the `const` modifier where applicable. Use it especially for
functions that take pointer arguments but do not modify the storage that the
argument points to. This is often the case with many text processing functions
that take strings as arguments but do not modify them. The `const`
modifier may help the compiler take advantage of additional optimization
opportunities, and more importantly it helps programmers. If a programmer sees
that a function takes a pointer to `const char`, he or she will
know that the string won't be modified so it's not necessary to create a copy
and it could be stored in read-only memory.

=== Use of 'static'

Use the `static` storage class liberally. It is important for both
the compiler and the programmer. The compiler may take advantage of additional
optimization opportunities; for instance, a static function that is always
inlined need not be emitted in its non-inline form. Keeping functions and
variables static also helps prevent name space pollution, as there is no danger
that objects with static storage might conflict with objects defined in other
modules. Static objects also greatly ease maintenance, because when modifying a
static variable or function, the maintainer must only examine the module where
the object is defined, without worrying about other modules.

=== Char Signedness

Do not assume that plain `char` is either signed or unsigned. Only
use plain `char` objects to hold text. Do not peform arithmetic
on such objects (except perhaps subtraction), and do not use them for indexing
into arrays. If necessary, declare such objects with explicit sign, or use
casts.

=== Structure Packing

Structure packing can be a source of interesting problems. To avoid most of
them, keep in mind the following recommendations.

For structures that are only used internally within a single project, it
is highly recommended to use compiler default packing. This is especially
important on platforms where misaligned accesses incur significant penalties
(that includes nearly all modern processor architectures) or raise processor
exceptions.

However, for structures that describe external data stored in files, received
over network links etc., proper alignment is ''critical''. In ideal cases,
structures are designed to be naturally aligned and structure packing
becomes irrelevant. In reality, many structures aren't naturally aligned
(especially those designed on non-RISC architectures or by incompetent
programmers) and proper packing must be specified. Problems caused by improper
structure packing are notoriously difficult to diagnose.

There is unfortunately no standardized way to specify structure packing.
However, the

----
#pragma pack( push, x )
...
#pragma pack( pop )
----

form is recommended, as it is supported by many compilers.

=== Enumeration Sizes

Do not assume that enumeration variables have specific size. They might be
`int` sized or they might not be. If you need to store enumeration
values in a structure with externally imposed layout, use a type with explicitly
specifed width for storage.

=== Endianness Issues

Write code that does not depend on ordering of bytes within words when
they are stored in memory. If the ordering is significant, provide two variants
of the code. Use the `+__BIG_ENDIAN__+` macro to test for big endian
targets. Be especially careful with unions and bitfields, as their layout will be
quietly altered when endianness changes.

When a sequence of bytes is stored in memory (a text string, for instance), keep
in mind that reading the storage as words or doublewords is going to have different
results on the 'other' platform.

=== Filesystem Naming Conventions

Don't get inventive with file names. Stick to alphanumeric characters, preferably
all lowercase, with no spaces or other funny characters. When writing code that
needs to parse pathnames, keep in mind that the path separator may be a forward slash,
a backslash, or (on Win32 or OS/2) either. Use the `+__UNIX__+` macro
to test if UNIX naming conventions should be followed.

=== File Creation and Opening

Make sure that files are opened with proper mode. While UNIX may not distinguish
between text and binary files, many other platforms do. Explicitly open binary
files as binary and text files as text.

On the other hand, when using POSIX style I/O, do not assume that the system
does not care about access flags. While Win32 may not have user/group/other
access flags, many other platforms do. When creating files, make sure
appropriate access rights are used.
