"Follow the rules."


The Difference Engine Coding Guide

This is an attempt to sort out the coding guidelines I am consciously or unconsciously using. It should help sorting out the reworked dE libraries.

Packages/Projects

Language

The language is ANSI C, compiled as C++, and C++ according to the proposed ANSI C++ standards. C++ features are used as implemented in GCC 2.7.2 or above, which unfortunately, means far from being complete. There is not stable stupport for namespaces, exceptions, RTTI. It seems that optimization is broken in some regards.

Files

File names are not DOS-restricted. The following conventions are used:

This means that a header only contains declarations. The inline definitions should be separated inside the header file. Convenient exception: single line inlines like { return _somthing; } in classes.

Any template definition (potential inline) has to be put in *.t.C.

There are alternatives using *.C files:

Names and Identifiers

Template Instantiation

As there won't be a working template instantiation repository mechanism for quite some time, we will rely on explicit template instantiation.

Thus we will have to handle the following fragment of code very often:

 #pragma implementation
 #include"this.H"
 #include"this.t.C"

 template <class T> tAnyBase_OfThisTemplate<tAnyType>;
 template <class T> tThisTemplate_Itself<tAnyType>;

Note that explicit instantiation means that any base (class) template has to be instantiated, too. This has to be done manually. Template instantiations will put into the same *.C files in which the implementation of the template parameter class is done.

Directory contents

The following files have to be present in every directory, and are maintained by CVS:

configure.in    - input for autoconf to generate configure
Makefile.in     - input for configure to generate Makefile
aclocal.m4      - for configure
The following files have to be available in ./bin:
install.sh      - for install

Source Tree

The following directories have to be present within the dE directory tree:

Include File locking

To avoid multiple inclusion by CPP, the following lines are used with SomeFile.H:

#ifndef __DE_SOME_FILE_H
#define __DE_SOME_FILE_H

#include <whatever.h>

#include "WhatEver.H"

#ifdef __GNUG__
#pragma interface
#endif

...

#endif

Note the use of Pragma, which corresponds to the following standard lines in the implementation *.C file only:

#include <whatever.h>

#include "WhatEver.H"

#ifdef __GNUG__
#pragma implementation "SomeFile.H"
#endif
#include "SomeFile.H"

Miscancellous

Pointer returns

Handling pointer return values: e.g. for the tString and tName classes, it will be necessary to convert const char* for I/O and other purposes. There are the following possible operators:


    operator       char*();         // Not done.
    operator       char*() const;   // Definitely not done.
    operator const char*();         // Note done. See below.
    operator const char*() const;   // Done.
 
In principle, pointer return values provide means to access the internal state of an object. This is not a good idea. We have to make sure that the object's content cannot be changed (thus const char*), and we indicate that the operation can be applied to const cObjects as well (thus operator () const). In principle, there is the possibility to use const char const *. I have to think each time, thus here it is:
            char*       something;    // Nothing is const.
      const char*       something;    //  content is const.
            char* const something;    //  pointer is const.
      const char* const something;    // Everything is const.
Obviously, as the pointer itself is just a variable, it makes no sense to require it being const. Thus protecting the content pointed to is sufficient.

Reference returns

The same considerations made for pointer return values apply to reference return values. In case of simpe scalar returns, it is a good idea to implement both

      char&  operator[] ( int index );
      char&  operator[] ( int index ) const;
for read/write access to non-const objects, and read-only access to const objects. In general, reference return values should be prefered, as it is not necessary to check for NULL (getting a type-secure NULL is a problem in itself). This will not work in all cases you want to return NULL if a requested object is not available.


home qdev qdev dread rsc qdev doom license web
home dEr95 r3D dread netrsc quake doom legal web
Author: b., email to bk@gamers.org, with public PGP key
Copyright (©) 1995-1998 by author. All rights reserved.
Source: $Id: coding.html,v 1.3 1996/06/13 10:55:57 b1 Exp $