Now in the wiki
authorSimon Marlow <simonmar@microsoft.com>
Wed, 6 Sep 2006 10:40:22 +0000 (10:40 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Wed, 6 Sep 2006 10:40:22 +0000 (10:40 +0000)
docs/comm/index.html
docs/comm/rts-libs/coding-style.html [deleted file]

index 5ccd5f0..294ba09 100644 (file)
@@ -82,7 +82,7 @@
     <h2>RTS &amp; Libraries</h2>
     <p>
     <ul>
-      <li><a href="rts-libs/coding-style.html">Coding Style Guidelines</a>
+      <li><a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/Conventions">Coding Style Guidelines</a>
       <li><a href="rts-libs/stgc.html">Spineless Tagless C</a>
       <li><a href="rts-libs/primitives.html">Primitives</a>
       <li><a href="rts-libs/prelfound.html">Prelude Foundations</a>
diff --git a/docs/comm/rts-libs/coding-style.html b/docs/comm/rts-libs/coding-style.html
deleted file mode 100644 (file)
index 58f5b4f..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-  <head>
-    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
-    <title>The GHC Commentary - Style Guidelines for RTS C code</title>
-  </head>
-
-<body>
-<H1>The GHC Commentary - Style Guidelines for RTS C code</h1>
-
-<h2>Comments</h2>
-
-<p>These coding style guidelines are mainly intended for use in
-<tt>ghc/rts</tt> and <tt>ghc/includes</tt>.
-
-<p>NB These are just suggestions.  They're not set in stone.  Some of
-them are probably misguided.  If you disagree with them, feel free to
-modify this document (and make your commit message reasonably
-informative) or mail someone (eg. <a
-href="glasgow-haskell-users@haskell.org">The GHC mailing list</a>)
-
-<h2>References</h2>
-
-If you haven't read them already, you might like to check the following.
-Where they conflict with our suggestions, they're probably right.
-
-<ul>
-
-<li>
-The C99 standard.  One reasonable reference is <a
-href="http://home.tiscalinet.ch/t_wolf/tw/c/c9x_changes.html">here</a>.
-
-<p><li>
-Writing Solid Code, Microsoft Press.  (Highly recommended.  Possibly
-the only Microsoft Press book that's worth reading.)
-
-<p><li>
-Autoconf documentation.
-See also <a href="http://peti.gmd.de/autoconf-archive/">The autoconf macro archive</a> and 
-<a href="http://www.cyclic.com/cyclic-pages/autoconf.html">Cyclic Software's description</a>
-
-<p><li> <a
-href="http://www.cs.umd.edu/users/cml/cstyle/indhill-cstyle.html">Indian
-Hill C Style and Coding Standards</a>.
-
-<p><li>
-<a href="http://www.cs.umd.edu/users/cml/cstyle/">A list of C programming style links</a>
-
-<p><li>
-<a href="http://www.lysator.liu.se/c/c-www.html">A very large list of C programming links</a>
-
-<p><li>
-<a href="http://www.geek-girl.com/unix.html">A list of Unix programming links</a>
-
-</ul>
-
-
-<h2>Portability issues</h2>
-
-<ul>
-<p><li> We try to stick to C99 where possible.  We use the following
-C99 features relative to C89, some of which were previously GCC
-extensions (possibly with different syntax):
-
-<ul>
-<p><li>Variable length arrays as the last field of a struct.  GCC has
-a similar extension, but the syntax is slightly different: in GCC you
-would declare the array as <tt>arr[0]</tt>, whereas in C99 it is
-declared as <tt>arr[]</tt>.
-
-<p><li>Inline annotations on functions (see later)
-
-<p><li>Labeled elements in initialisers.  Again, GCC has a slightly
-different syntax from C99 here, and we stick with the GCC syntax until
-GCC implements the C99 proposal.
-
-<p><li>C++-style comments.  These are part of the C99 standard, and we
-prefer to use them whenever possible.
-</ul>
-
-<p>In addition we use ANSI-C-style function declarations and
-prototypes exclusively.  Every function should have a prototype;
-static function prototypes may be placed near the top of the file in
-which they are declared, and external prototypes are usually placed in
-a header file with the same basename as the source file (although there
-are exceptions to this rule, particularly when several source files
-together implement a subsystem which is described by a single external
-header file).
-
-<p><li>We use the following GCC extensions, but surround them with
-<tt>#ifdef __GNUC__</tt>:
-
-<ul>
-<p><li>Function attributes (mostly just <code>no_return</code> and
-<code>unused</code>)
-<p><li>Inline assembly.
-</ul>
-
-<p><li>
-char can be signed or unsigned - always say which you mean
-
-<p><li>Our POSIX policy: try to write code that only uses POSIX (IEEE
-Std 1003.1) interfaces and APIs.  We used to define
-<code>POSIX_SOURCE</code> by default, but found that this caused more
-problems than it solved, so now we require any code that is
-POSIX-compliant to explicitly say so by having <code>#include
-"PosixSource.h"</code> at the top.  Try to do this whenever possible.
-
-<p><li> Some architectures have memory alignment constraints.  Others
-don't have any constraints but go faster if you align things.  These
-macros (from <tt>ghcconfig.h</tt>) tell you which alignment to use
-
-<pre>
-  /* minimum alignment of unsigned int */
-  #define ALIGNMENT_UNSIGNED_INT 4
-
-  /* minimum alignment of long */
-  #define ALIGNMENT_LONG 4
-
-  /* minimum alignment of float */
-  #define ALIGNMENT_FLOAT 4
-
-  /* minimum alignment of double */
-  #define ALIGNMENT_DOUBLE 4
-</pre>
-
-<p><li> Use <tt>StgInt</tt>, <tt>StgWord</tt> and <tt>StgPtr</tt> when
-reading/writing ints and ptrs to the stack or heap.  Note that, by
-definition, <tt>StgInt</tt>, <tt>StgWord</tt> and <tt>StgPtr</tt> are
-the same size and have the same alignment constraints even if
-<code>sizeof(int) != sizeof(ptr)</code> on that platform.
-
-<p><li> Use <tt>StgInt8</tt>, <tt>StgInt16</tt>, etc when you need a
-certain minimum number of bits in a type.  Use <tt>int</tt> and
-<tt>nat</tt> when there's no particular constraint.  ANSI C only
-guarantees that ints are at least 16 bits but within GHC we assume
-they are 32 bits.
-
-<p><li> Use <tt>StgFloat</tt> and <tt>StgDouble</tt> for floating
-point values which will go on/have come from the stack or heap.  Note
-that <tt>StgDouble</tt> may occupy more than one <tt>StgWord</tt>, but
-it will always be a whole number multiple.
-
-<p>
-Use <code>PK_FLT(addr)</code>, <code>PK_DBL(addr)</code> to read
-<tt>StgFloat</tt> and <tt>StgDouble</tt> values from the stack/heap,
-and <code>ASSIGN_FLT(val,addr)</code> /
-<code>ASSIGN_DBL(val,addr)</code> to assign StgFloat/StgDouble values
-to heap/stack locations.  These macros take care of alignment
-restrictions.
-
-<p>
-Heap/Stack locations are always <tt>StgWord</tt> aligned; the
-alignment requirements of an <tt>StgDouble</tt> may be more than that
-of <tt>StgWord</tt>, but we don't pad misaligned <tt>StgDoubles</tt>
-because doing so would be too much hassle (see <code>PK_DBL</code> &
-co above).
-
-<p><li>
-Avoid conditional code like this:
-
-<pre>
-  #ifdef solaris_host_OS
-  // do something solaris specific
-  #endif
-</pre>
-
-Instead, add an appropriate test to the configure.ac script and use
-the result of that test instead. 
-
-<pre>
-  #ifdef HAVE_BSD_H
-  // use a BSD library
-  #endif
-</pre>
-
-<p>The problem is that things change from one version of an OS to another
-- things get added, things get deleted, things get broken, some things
-are optional extras.  Using "feature tests" instead of "system tests"
-makes things a lot less brittle.  Things also tend to get documented
-better.
-
-</ul>
-
-<h2>Debugging/robustness tricks</h2>
-
-
-Anyone who has tried to debug a garbage collector or code generator
-will tell you: "If a program is going to crash, it should crash as
-soon, as noisily and as often as possible."  There's nothing worse
-than trying to find a bug which only shows up when running GHC on
-itself and doesn't manifest itself until 10 seconds after the actual
-cause of the problem.
-
-<p>We put all our debugging code inside <tt>#ifdef DEBUG</tt>.  The
-general policy is we don't ship code with debugging checks and
-assertions in it, but we do run with those checks in place when
-developing and testing.  Anything inside <tt>#ifdef DEBUG</tt> should
-not slow down the code by more than a factor of 2.
-
-<p>We also have more expensive "sanity checking" code for hardcore
-debugging - this can slow down the code by a large factor, but is only
-enabled on demand by a command-line flag.  General sanity checking in
-the RTS is currently enabled with the <tt>-DS</tt> RTS flag.
-
-<p>There are a number of RTS flags which control debugging output and
-sanity checking in various parts of the system when <tt>DEBUG</tt> is
-defined.  For example, to get the scheduler to be verbose about what
-it is doing, you would say <tt>+RTS -Ds -RTS</tt>.  See
-<tt>includes/RtsFlags.h</tt> and <tt>rts/RtsFlags.c</tt> for the full
-set of debugging flags.  To check one of these flags in the code,
-write:
-
-<pre>
-  IF_DEBUG(gc, fprintf(stderr, "..."));
-</pre>
-
-would check the <tt>gc</tt> flag before generating the output (and the
-code is removed altogether if <tt>DEBUG</tt> is not defined).
-
-<p>All debugging output should go to <tt>stderr</tt>.
-
-<p>
-Particular guidelines for writing robust code:
-
-<ul>
-<p><li>
-Use assertions.  Use lots of assertions.  If you write a comment
-that says "takes a +ve number" add an assertion.  If you're casting
-an int to a nat, add an assertion.  If you're casting an int to a char,
-add an assertion.  We use the <tt>ASSERT</tt> macro for writing
-assertions; it goes away when <tt>DEBUG</tt> is not defined.
-
-<p><li>
-Write special debugging code to check the integrity of your data structures.
-(Most of the runtime checking code is in <tt>rts/Sanity.c</tt>)
-Add extra assertions which call this code at the start and end of any
-code that operates on your data structures.
-
-<p><li>
-When you find a hard-to-spot bug, try to think of some assertions,
-sanity checks or whatever that would have made the bug easier to find.
-
-<p><li>
-When defining an enumeration, it's a good idea not to use 0 for normal
-values.  Instead, make 0 raise an internal error.  The idea here is to
-make it easier to detect pointer-related errors on the assumption that
-random pointers are more likely to point to a 0 than to anything else.
-
-<pre>
-typedef enum
-    { i_INTERNAL_ERROR  /* Instruction 0 raises an internal error */
-    , i_PANIC           /* irrefutable pattern match failed! */
-    , i_ERROR           /* user level error */
-
-    ...
-</pre>
-
-<p><li> Use <tt>#warning</tt> or <tt>#error</tt> whenever you write a
-piece of incomplete/broken code.
-
-<p><li> When testing, try to make infrequent things happen often.
-     For example, make a context switch/gc/etc happen every time a 
-     context switch/gc/etc can happen.  The system will run like a 
-     pig but it'll catch a lot of bugs.
-
-</ul>
-
-<h2>Syntactic details</h2>
-
-<ul>
-<p><li><b>Important:</b> Put "redundant" braces or parens in your code.
-Omitting braces and parens leads to very hard to spot bugs -
-especially if you use macros (and you might have noticed that GHC does
-this a lot!)
-
-<p>
-In particular:
-<ul>
-<p><li>
-Put braces round the body of for loops, while loops, if statements, etc.
-even if they "aren't needed" because it's really hard to find the resulting
-bug if you mess up.  Indent them any way you like but put them in there!
-</ul>
-
-<p><li>
-When defining a macro, always put parens round args - just in case.
-For example, write:
-<pre>
-  #define add(x,y) ((x)+(y))
-</pre>
-instead of
-<pre>
-  #define add(x,y) x+y
-</pre>
-
-<p><li> Don't declare and initialize variables at the same time.
-Separating the declaration and initialization takes more lines, but
-make the code clearer.
-
-<p><li>
-Use inline functions instead of macros if possible - they're a lot
-less tricky to get right and don't suffer from the usual problems
-of side effects, evaluation order, multiple evaluation, etc.
-
-<ul>
-<p><li>Inline functions get the naming issue right.  E.g. they
-  can have local variables which (in an expression context)
-  macros can't.
-
-<p><li> Inline functions have call-by-value semantics whereas macros
-  are call-by-name.  You can be bitten by duplicated computation
-  if you aren't careful.
-
-<p><li> You can use inline functions from inside gdb if you compile with
-  -O0 or -fkeep-inline-functions.  If you use macros, you'd better
-  know what they expand to.
-</ul>
-
-However, note that macros can serve as both l-values and r-values and
-can be "polymorphic" as these examples show:
-<pre>
-  // you can use this as an l-value or an l-value
-  #define PROF_INFO(cl) (((StgClosure*)(cl))->header.profInfo)
-
-  // polymorphic case
-  // but note that min(min(1,2),3) does 3 comparisions instead of 2!!
-  #define min(x,y) (((x)<=(y)) ? (x) : (y))
-</pre>
-
-<p><li>
-Inline functions should be "static inline" because:
-<ul>
-<p><li>
-gcc will delete static inlines if not used or theyre always inlined.
-
-<p><li>
-  if they're externed, we could get conflicts between 2 copies of the 
-  same function if, for some reason, gcc is unable to delete them.
-  If they're static, we still get multiple copies but at least they don't conflict.
-</ul>
-
-OTOH, the gcc manual says this
-so maybe we should use extern inline?
-
-<pre>
-   When a function is both inline and `static', if all calls to the
-function are integrated into the caller, and the function's address is
-never used, then the function's own assembler code is never referenced.
-In this case, GNU CC does not actually output assembler code for the
-function, unless you specify the option `-fkeep-inline-functions'.
-Some calls cannot be integrated for various reasons (in particular,
-calls that precede the function's definition cannot be integrated, and
-neither can recursive calls within the definition).  If there is a
-nonintegrated call, then the function is compiled to assembler code as
-usual.  The function must also be compiled as usual if the program
-refers to its address, because that can't be inlined.
-
-   When an inline function is not `static', then the compiler must
-assume that there may be calls from other source files; since a global
-symbol can be defined only once in any program, the function must not
-be defined in the other source files, so the calls therein cannot be
-integrated.  Therefore, a non-`static' inline function is always
-compiled on its own in the usual fashion.
-
-   If you specify both `inline' and `extern' in the function
-definition, then the definition is used only for inlining.  In no case
-is the function compiled on its own, not even if you refer to its
-address explicitly.  Such an address becomes an external reference, as
-if you had only declared the function, and had not defined it.
-
-   This combination of `inline' and `extern' has almost the effect of a
-macro.  The way to use it is to put a function definition in a header
-file with these keywords, and put another copy of the definition
-(lacking `inline' and `extern') in a library file.  The definition in
-the header file will cause most calls to the function to be inlined.
-If any uses of the function remain, they will refer to the single copy
-in the library.
-</pre>
-
-<p><li>
-Don't define macros that expand to a list of statements.  
-You could just use braces as in:
-
-<pre>
-  #define ASSIGN_CC_ID(ccID)              \
-        {                                 \
-        ccID = CC_ID;                     \
-        CC_ID++;                          \
-        }
-</pre>
-
-(but it's usually better to use an inline function instead - see above).
-
-<p><li>
-Don't even write macros that expand to 0 statements - they can mess you 
-up as well.  Use the doNothing macro instead.
-<pre>
-  #define doNothing() do { } while (0)
-</pre>
-
-<p><li>
-This code
-<pre>
-int* p, q;
-</pre>
-looks like it declares two pointers but, in fact, only p is a pointer.
-It's safer to write this:
-<pre>
-int* p;
-int* q;
-</pre>
-You could also write this:
-<pre>
-int *p, *q;
-</pre>
-but it is preferrable to split the declarations.
-
-<p><li>
-Try to use ANSI C's enum feature when defining lists of constants of
-the same type.  Among other benefits, you'll notice that gdb uses the
-name instead of its (usually inscrutable) number when printing values
-with enum types and gdb will let you use the name in expressions you
-type.  
-
-<p>
-Examples:
-<pre>
-    typedef enum { /* N.B. Used as indexes into arrays */
-     NO_HEAP_PROFILING,                
-     HEAP_BY_CC,               
-     HEAP_BY_MOD,              
-     HEAP_BY_GRP,              
-     HEAP_BY_DESCR,            
-     HEAP_BY_TYPE,             
-     HEAP_BY_TIME              
-    } ProfilingFlags;
-</pre>
-instead of
-<pre>
-    # define NO_HEAP_PROFILING 0       /* N.B. Used as indexes into arrays */
-    # define HEAP_BY_CC                1
-    # define HEAP_BY_MOD       2
-    # define HEAP_BY_GRP       3
-    # define HEAP_BY_DESCR     4
-    # define HEAP_BY_TYPE      5
-    # define HEAP_BY_TIME      6
-</pre>
-and 
-<pre>
-    typedef enum {
-     CCchar    = 'C',
-     MODchar   = 'M',
-     GRPchar   = 'G',
-     DESCRchar = 'D',
-     TYPEchar  = 'Y',
-     TIMEchar  = 'T'
-    } ProfilingTag;
-</pre>
-instead of
-<pre>
-    # define CCchar    'C'
-    # define MODchar   'M'
-    # define GRPchar   'G'
-    # define DESCRchar 'D'
-    # define TYPEchar  'Y'
-    # define TIMEchar  'T'
-</pre>
-
-<p><li> Please keep to 80 columns: the line has to be drawn somewhere,
-and by keeping it to 80 columns we can ensure that code looks OK on
-everyone's screen.  Long lines are hard to read, and a sign that the
-code needs to be restructured anyway.
-
-<p><li> When commenting out large chunks of code, use <code>#ifdef 0
-... #endif</code> rather than <code>/* ... */</code> because C doesn't
-have nested comments.
-
-<p><li>When declaring a typedef for a struct, give the struct a name
-as well, so that other headers can forward-reference the struct name
-and it becomes possible to have opaque pointers to the struct.  Our
-convention is to name the struct the same as the typedef, but add a
-leading underscore.  For example:
-
-<pre>
-  typedef struct _Foo {
-    ...
-  } Foo;
-</pre>
-
-<p><li>Do not use <tt>!</tt> instead of explicit comparison against
-<tt>NULL</tt> or <tt>'\0'</tt>;  the latter is much clearer.
-
-<p><li> We don't care too much about your indentation style but, if
-you're modifying a function, please try to use the same style as the
-rest of the function (or file).  If you're writing new code, a
-tab width of 4 is preferred.
-
-</ul>
-
-<h2>CVS issues</h2>
-
-<ul>
-<p><li>
-Don't be tempted to reindent or reorganise large chunks of code - it
-generates large diffs in which it's hard to see whether anything else
-was changed.
-<p>
-If you must reindent or reorganise, don't include any functional
-changes that commit and give advance warning that you're about to do
-it in case anyone else is changing that file.
-</ul>
-
-
-</body>
-</html>