Geas MUD, enter the Aventure!
Geas Home | Play the Game

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

vi - Writing code

It might seem premature to tell you what your code should look like before you have learnt how to write it. However, it is a fundamental subject of great importance. Someone jokingly said that writing code correctly will make your teeth whiter, your hair darker and improve your sex life. Well... it might not do that, but it'll certainly improve the overall quality of what you produce, at a very low cost. Mainly it's a matter of self-discipline.

Here are some good arguments for making the effort:

What follows here is a rather lengthy instruction of how to put down your code in writing. Read it now even though you might not fully understand what is being discussed, then go back and re-read it later after having learnt the skills necessary. Doing that will make sure you'll remember the correct way of formatting your code.

  1. One indent level is 4 spaces long, no more, no less. A new indent level is started at the beginning of each block.

  2. Reserved words have a space after them, before the opening (, if any.

    while (test)

  3. Block brackets start and end in the same column; the column of the first letter in a statement opening a block.

    if (this)
    else if (that)

    Now, this is almost a religious matter for some coders. Representatives for another sect preaches that the block opening brace should be on the end of the line of the block statement and how you do this really isn't that important. Not as long as you do it exactly the way I say, or you'll burn in COBOL hell forever :) No, seriously, pick one of the two ways of doing it and stick to it. What is really important is that you keep the indention-level straight throughout the code. If we all agree on something, it's that wavy indention-levels is something not to be tolerated.

    As it happens, using almost any of the freely available editors for writing C-code (I recommend emacs) will take care of this problem for you, and at the same time provide some rudimentary syntax-checking functionality.

  4. Several arguments on a line separated by a comma or a semicolon have a space following the comma or semicolon. Binary operators have a space both in front of, and after the operator.

    int a, b, c;
    for (a = 0; a < 10; a++)
        b = function_call(a, b * 2);
        c = b * 3 / 4;

  5. If a loop statement has no body, put the ending ; on a separate line.

    while (!(var = func(var)))

    The reason for this is that if you should put it on the same line, it's very easy to miss real mistakes like this one just out of pure laziness:

    for (i = 0; i < 100; i++);
        <code that gets executed only once, but always>

  6. All #define and #include statements should be placed at the top of the file. It's possible to spread them out, but that will just be confusing.

  7. The same goes for prototypes and global/static variables used in the file. Clump them all together, with a proper comment header, in the top of the file. It's possible to spread them out, but oh how easy it is to miss them when reading the code later...

  8. Declarations of functions have the return type on a separate line from the function name.

    public void
    my_function(int a, int b)
        < code >

  9. Break long lines of code in proper places so that they don't wrap on their own beyond the end of a 80-width screen. It looks ugly and becomes hard to read, not to mention print.

  10. The file should begin with a proper header following this outline:

     * <filename>
     * <Short description of what the file does, no more than 5-7 lines.
     * ...
     * ... >
     * Copyright (C): <your name and year>

    Read the game Copyright statement NOW in order to know what rules apply to code you produce for the game, in the game. It ought to reside in the file `/doc/COPYRIGHT'. If not, simply ask one of the game administrators.

  11. Start every function with a header looking like this:

     * Arguments:     <A list of all arguments, one per line
     *                 arg1 - description no longer than the line.
     *                 arg2 - next argument, etc. >
     * Returns:       <What the function returns>

    If the function doesn't take any arguments, or doesn't return anything, keep the fields anyway and put in the text None. That way it is clear that you haven't forgotten anything, but in fact intended for the function to look the way it does.

  12. Put suitable comments in the code here and there when doing something that might look a bit obscure. Remember also that on your (assumed) level of competence, a lot of things are obscure :) Use your own judgement.

     * Comment for code following this comment,
     * telling what it does
    < code >

  13. Make sure all function names and local variables are written in lowercase alphabetical characters, possibly spacing words with an underscore (e.g. function_name()). Global variables should be written using the first letter of the word capitalized (e.g. int GlobalTime;). #defines should be written in capitals (e.g. #define AMOEBA "one celled creature"). Doing this makes it easy to see what kind of symbol is being handled at all times.

Now, the easiest way of getting the basic stuff done properly is to use the emacs editor, set up to use a modified c++ mode. The c++ mode understands about ::-operators but needs a few hints on tab stops etc. Put these lines of code into your .emacs file and all will work just as it should:

;; emacs lisp script start

(setq auto-mode-alist (append '(
  ("\\.l" . my-c++-mode)
  ("\\.y" . my-c++-mode)
  ("\\.c" . my-c++-mode)
  ("\\.h" . my-c++-mode))

(defun my-c++-mode () (interactive)
  (setq c-basic-offset 4)
  (setq c-offsets-alist
	'((string                . -1000)
	  (c                     . c-lineup-C-comments)
	  (defun-open            . 0)
	  (defun-close           . 0)
	  (defun-block-intro     . +)
	  (class-open            . -)
	  (class-close           . 0)
	  (inline-open           . +)
	  (inline-close          . 0)
	  (ansi-funcdecl-cont    . +)
	  (knr-argdecl-intro     . +)
	  (knr-argdecl           . 0)
	  (topmost-intro         . 0)
	  (topmost-intro-cont    . 0)
	  (member-init-intro     . +)
	  (member-init-cont      . 0)
	  (inher-intro           . +)
	  (inher-cont            . c-lineup-multi-inher)
	  (block-open            . 0)
	  (block-close           . 0)
	  (brace-list-open       . 0)
	  (brace-list-close      . 0)
	  (brace-list-intro      . +)
	  (brace-list-entry      . 0)
	  (statement             . 0)
	  ;; some people might prefer
	  ;;(statement             . c-lineup-runin-statements)
	  (statement-cont        . +)
	  ;; some people might prefer
	  ;;(statement-cont        . c-lineup-math)
	  (statement-block-intro . +)
	  (statement-case-intro  . +)
	  (statement-case-open   . 0)
	  (substatement          . +)
	  (substatement-open     . 0)
	  (case-label            . 0)
	  (access-label          . -)
	  (label                 . 2)
	  (do-while-closure      . 0)
	  (else-clause           . 0)
	  (comment-intro         . c-lineup-comment)
	  (arglist-intro         . +)
	  (arglist-cont          . 0)
	  (arglist-cont-nonempty . c-lineup-arglist)
	  (arglist-close         . +)
	  (stream-op             . c-lineup-streamop)
	  (inclass               . +)
	  (cpp-macro             . -1000)
	  (friend                . 0)
	  (objc-method-intro     . -1000)
	  (objc-method-args-cont . c-lineup-ObjC-method-args)
	  (objc-method-call-cont . c-lineup-ObjC-method-call)

  ;; emacs end

An added advantage of using emacs is that later, when debugging other coder's attempts at writing code, correcting their horrible indention is as easy as typing 'M-<', 'M->', 'M-C-\'.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Ronny Wikh on July, 8 2003 using texi2html