gnu-arch-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnu-arch-users] Re: Linus Torvalds <address@hidden> Re: log-buf-len


From: Tom Lord
Subject: Re: [Gnu-arch-users] Re: Linus Torvalds <address@hidden> Re: log-buf-len dynamic
Date: Wed, 8 Oct 2003 08:13:35 -0700 (PDT)


    > From: Zack Brown <address@hidden>

    > On Tue, Oct 07, 2003 at 05:45:08PM -0700, Tom Lord wrote:

    > >     > From: Zack Brown <address@hidden>

    > >     > I notice there are not so many comments in the sources. Has anyone
    > >     > considered working up a "developer's guide" to hacking tla? That 
would
    > >     > be really cool.

    > > Yeah, sorry about that..... pure "speed hacking" there.   

    > Tom, maybe you could publish guidelines for the kind/style of comment
    > that you'd find acceptable for folks to submit.


General style notes based on common style errors in submitted code (in
no particular order, certainly incompletely, and yes, I don't follow
these rules perfectly myself):

1) Length of code lines

   Please use a very wide editor window and create long lines rather
   than statements
      broken up
      across
      many short
      lines.

   An upper bound of around 170 characters is not unreasonable.
   (This allows much more of the code from a given file to be visible
   on the screen at once.)


2) GNU whitespace conventions

   Put each brace on its own line.

   The indenting level is 2 spaces.  Outdent case labels and goto
   labels by 2 spaces, except for goto-labels in outermost blocks
   which are outdented by one space.

   Put a space before the ( in a function call:  

       foo ();          not     foo();

   Put spaces around all binary operators:  

        x = y;          not     x=y;

   Put a space before conditional expressions:

        if (...)                if(...)
          ..                      ..
                        not
        for (...)               for(...)
          ..                      ..

   Put function names in definitions in column 0:

        int                     int x (void)
        x (void)        not     {
        {                         ...
          ...                   }
        }

   Put a blank line after local declarations in a block.


3) Use assignment operators as statements, not expressions.

       x = foo ();      not     y = 1 + (x = foo ());
       y = x + 1;


4) Usually, use increment/decrement operators as statements, not
   expressions. 

        y = a[x];       not     y = a[x++];
        ++x;


5) Use spaces, not tabs.


6) Return parameters go first in argument lists

   and often should be optional:


        int
        x (int * other_ret, int param)
        {
          int other;

          other = foo (param);

          if (other_ret)
            *other_ret = other;

          return bar (param);
        }


7) Comments

   Comments are the exception to the long line rule.  They should be
   formatted for 80 column display.

   With a very few exceptions (e.g., comments on structure fields), 
   comments go on lines by themselves, formatted like this:

        /* this is a short comment
         */


         /* this is a longer comment
          * that spans more than 
          * one line of text.
          */

   A comment that labels a file section should be preceeded by a 
   formfeed, a line with 64 asterisks, and a title:

         ^L
         /****************************************************************
          * title of section
          * 
          * optional brief description of section.
          */

   Mostly, you should avoid writing very long functions but sometimes
   that is the cleanest way.   If a long function breaks down into
   sections, the comment for a section does not have a formfeed,
   uses 32 asterisks, and is indented with the surrounding code.

         /********************************
          * title of function section
          * 
          * optional brief description
          */

   Note that all of the comment styles end with "*/" on a line by
   itself and do _not_ start with "/*" on a line by itself.
   Comments should almost always precede the thing they comment.

   Very occaisionally, it makes sense to write a comment that
   _follows_ the thing it comments.   In that case, the comment
   _should_ start with "/*" on a line by itself:

            /*
             * this comment describes what precedes
             * it.
             */


   It is mostly too early to provide complete man-page-style comments
   describing what each function does.   If you're interested in
   writing such, it should be done in the context of cleaning up the
   calling conventions and refactoring a little bit.

   There is no need to comment excessively -- comment only where you
   think the code will be too hard to read.


8) Rule of thumb for returns:

   Not a hard and fast rule but for the most part, each function
   should have exactly one return statement (or exactly 0 for void
   functions).


9) Allocation and cleanups

   If the value of a local variable is dynamically allocated, the
   declaration of that variable should initialize it to 0.

   As a rule of thumb, there should be one block of code that frees
   allocated values.   That block of code should be robust in the face
   of some values being 0.   (Usually this is automatic: libhackerlab
   `free'-like functions are robust given a null argument.)

   If a function needs to exit from multiple points in the code, it
   should do so with a goto to the cleanup block:

        int
        fn (....)
        {
          t_uchar * some_var = 0;
          t_uchar * other_var = 0;
          t_uchar * p;
          int answer = -1;

          some_var = some_allocated_result (...);

          for (p = some_var; *p; ++p)
            {
              ..... (maybe `goto done') ....
              ..... (maybe set other_var) ....
              ..... (maybe set answer) ....
            }

         done:
          lim_free (0, some_var);
          lim_free (0, other_var);

          return answer;
        }


10) Use invariants especially where you are uncertain

    Using definitions from:

        #include "hackerlab/bugs/panic.h"

    feel free to sprinkle your code with invariant assertions:

        invariant (n_files > 5);

    If the condition (which must be an integer expression) evaluates 
    to 0 at run-time, the program will be aborted with an error
    message that says which invariant was violated.


11) Compile cleanly with -Wall

    This is a tricky one.   For some versions of GCC, it already
    doesn't compile cleanly with -Wall.   These warnings are being
    slowly cleaned up.   (The process is slow since recent versions of
    GCC do not work correctly on my platform and because some warnings
    only show up on platforms to which I have only slow access.)

    Still, please try to avoid very basic warnings such as for
    undeclared functions and unused variables.


12) File layout

    Every .c file has a corresponding .h file with declarations for
    all functions exported from that file.   I use some emacs tools to
    automatically update them but if you don't, please fix them up by
    hand.  

    The general layout of a .c file is (I've used '^' 'L' to indicate
    a formfeed):

        /* thisfile.c:  <optional short description>
         *
         ****************************************************************
         * <copyright boilerplate>
         */
        ^L

        #include directives
        #include "tla/libarch/thisfile.h"

        ^L
        /* __STDC__ prototypes for static functions */
        <forward declarations of static functions> 

        ^L
        <optional section: local type and variable declarations>

        ^L
        <one or more section: exported functions>

        ^L
        <zero or more sections: static functions>

        ^L
        /* tag: .....
         */


    There should be two blank lines between functions in a given
    section.

    Every file should include its own .h file, last in the list of
    includes.

    Optionally, begin sections with a comment:

        ^L
        /****************************************************************
         * <title of section>
         * 
         * <brief description>
         */

    The idea of these conventions is to make it easy to navigate the
    files with "page-up" and "page-down" functions (that move to the 
    next form-feed).


13) Use parentheses, not operator precedence

        a + (x * y)     not     a + x * y

    and so forth


14) In libarch, avoid error returns

    A function may encounter an error while doing its work.

    If it is certain that some callers will want to handle that error,
    then fine, return an error code.   Normally, though, the error
    should just cause an error message to be printed on stderr
    followed by an `exit (2)'.


15) There _is_ a manual for libhackerlab

    The project docs-hackerlab--devo--1.0 contains preformatted
    copies.   The source for the manual is in comments in
    libhackerlab.


16) The mysteries of src/tla/libawk

    Compare these functions to unix commands like sort(1), join(1), 
    and so forth.   Compare associative arrays to the associative
    arrays in a language like awk.


17) self-standing header files

    A header file is layed out this way:

    /* thisfile.h: <optional short description>
     *
     ****************************************************************
     * <copyright boilerplate>
     */
    ^L

    #include directives

    

    <type and extern variable declarations>

    ^L
    /* automatically generated __STDC__ prototypes */
    <extern function declarations>

    ^L
    /* tag: .....
     */

    The include directives in a header file should be sufficient to 
    to make all of the declarations in the header valid.   In other
    words, it should never be necessary to include foo.h before
    including bar.h.

    Include directives should always use the path relative to the
    `src' directory:

  #include "tla/libarch/pristines.h" not #include "pristines.h"

    For the most part, do not include system header files directly.
    Use the libhackerlab wrappers instead:

  #include "hackerlab/os/stdarg.h"  not #include <stdarg.h>


18) Plus everything else that I forgot to mention.


-t





reply via email to

[Prev in Thread] Current Thread [Next in Thread]