summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-09-06 10:40:22 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-09-06 10:40:22 +0000
commit82af8c0af70a1f72d5c364d35d04eef17d88395d (patch)
tree5164577d7b6230420be4646dd638a50d58755bd1
parentabcf8d64e9d687e015f7f50938b4cd006f277114 (diff)
downloadhaskell-82af8c0af70a1f72d5c364d35d04eef17d88395d.tar.gz
Now in the wiki
-rw-r--r--docs/comm/index.html2
-rw-r--r--docs/comm/rts-libs/coding-style.html516
2 files changed, 1 insertions, 517 deletions
diff --git a/docs/comm/index.html b/docs/comm/index.html
index 5ccd5f0ca9..294ba0982a 100644
--- a/docs/comm/index.html
+++ b/docs/comm/index.html
@@ -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
index 58f5b4f9bb..0000000000
--- a/docs/comm/rts-libs/coding-style.html
+++ /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>