Next: Suggestions Up: NIL/PIL Coding Guidelines Previous: Requirements

Strong Suggestions

Global variables are highly undesirable. Even static variables within a file are undesirable, especially when used to avoid passing parameters. With as few exceptions as possible, all variables accessed by a function should be parameters to it or locals. This allows people reading the code to be able to understand a function without looking outside the function code itself. Also it allows a function to be relocated to another file without relying on static variables within the original file.

An example of a valid use of global variables would be as run-time constants, i.e., values which might be initialized at the beginning of the program, and then accessed in a read-only manner.

Continuation lines of functions should line up with the '(', if reasonable:



    x = find_shortest_path( p1, p2, p3,
                            parameter4,
                            parameter5 );
Exception: (if no room)


                  {
                      x = find_shortest_path(
                                parameter1,
                                parameter2,
                                parameter3,
                                parameter4,
                                parameter5,
                                parameter6 );
                  }

In most cases, you should use a defined constant instead of a numerical constant, as a documentation aid:
WRONG:



    index = day / 7;
RIGHT:


    index = day / NUMBER_DAYS_IN_WEEK;

Exceptions to this rule occur where it is clearer and easier to maintain correctness by using an explicit numerical constant:



    avg = (p1 + p2 + p3 + p4) / 4;

Never do this:



        while( function() );
because someone might someday add code for the body of the loop, and forget to take out the semicolon:


        while( function() );
        {
            body();
        }
The above is valid C code, but does not do what is required. Use:


        while( function() )
        {
        }

For structures that are 8 bytes or more, it is much more efficient to pass by reference, rather than value, for most compilers.



        public  void  function( parameter )
            image_struct   *parameter;
        {
        }

Full-line comments should be at the same indentation level as the code, with a blank line above and below. Same-line comments should be separated from the code by many spaces:



    n = 10;

    /* find the largest value in the array */

    max = a[0];

    for( i = 1;  i < n;  ++i )
    {
        if( a[i] > max )
        {
            max = a[i];         /* new max */
        }
    }

    c = max;         /* initialize counter */

Use enumerated types for variables with a limited number of values.
WRONG:



    #define  MR_FORMAT     1
    #define  PET_FORMAT    2
    #define  IFF_FORMAT    3
    #define  FREE_FORMAT   4

    main()
    {
       int  input_format;

       input_format = MR_FORMAT;
    }
RIGHT:


    typedef  enum {
                      MR_FORMAT,
                      PET_FORMAT,
                      IFF_FORMAT,
                      FREE_FORMAT
                  } file_format_types;

    main()
    {
       file_format_types  input_format;

       input_format = MR_FORMAT;
    }

Use explicit type-casting whenever conversion between types is to be done:



    {
        int      int_x;
        float    float_x;

        float_x = 3.56;

        int_x = (int) float_x;
    }

    {
        voxel_struct  *current_voxel;

        if( current_voxel == (voxel_struct *) 0 )
        {
            exit( 1 );
        }
    }

Never treat integers like booleans (flags). Never treat booleans like integers:
WRONG:



    {
        int   invert_flag;
        int   number_of_slices;

        if( number_of_slices )
        {
        }

        if( invert_flag == 0 )
        {
        }
    }
RIGHT


    {
        int   invert_flag;
        int   number_of_slices;

        if( number_of_slices != 0 )
        {
        }

        if( !invert_flag )
        {
        }
    }

One possible exception is:


    /* returns 0 or an error */

    if( input_file( file, data ) )
    {
        (void) print( "Error\n" );
    }



Next: Suggestions Up: NIL/PIL Coding Guidelines Previous: Requirements


neelin@bic.mni.mcgill.ca
Tue Mar 22 16:51:19 EST 1994