Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous
Next: Guidelines Up: AIPS++ Programming Standards DRAFT Version Previous: Introduction

Subsections


Standards

0 and NULL

The integer constant 0 should be used instead of the usual NULL from <stdio.h> or <string.h>. In C, this #define was used to insure that pointer assignments had the proper size. In C++, however, this can result in type mismatch problems, e.g. NULL may be defined to be (void *)0. Zero,``0'', holds a special place in the C++ type system because even though zero's type is int, it is automatically cast to any pointer, char, or float. (See p.30 Plum, p.87 Meyers, p.35 ARM)

Header Files

Every include file must have protecting #if defined()s to prevent multiple inclusion, so for ``aips.h'' the include file would be enclosed by:
\#if !defined(AIPS\_H\_)
\#define AIPS\_H\_

           BODY OF INCLUDE FILE

\#endif

Header files should not initialize values. The user of a given header file should be assured that including the header file will not increase the object-code size. This practice forces the data to be owned by a given source file, and avoids complicated initialization constructs in the header files. (See p.154 Plum)

const, #define, and macros

Constants, #defines, and macros, should have the smallest scope possible; restricted to a single source file when possible to avoid name clashes. The C++ const, inline, and enum facilities should be used as opposed to defines, because these facilities provide a typesafe means of defining constants, as opposed to the preprocessor which defeats the type system, and can make macro bugs difficult to find. Sometimes, however, #defines must be used, for example include file protection against multiple includes.

Another example of preprocessor utility is the ## operator for concatenation of tokens. This has no equivalent operation in C++. In addition, #ifdefs also provide the only reasonable means of conditional compilation. e.g.

\#if defined(\_\_cplusplus)
           C++ CODE
\#elif defined(\_\_STDC\_\_)
           ANSI C CODE
\#else
           K\&R C CODE
\#endif

With the exception of include file protection, preprocessor functions should be used with caution. The ## operator, for example, is not available on K&R C compilers. The typical work around is to define a macro which uses an empty comment, /**/, for concatenation. Careless ifdefs for conditional compilation throughout code make it difficult to maintain.

When the preprocessor is utilized macro or defines which begin with a double underscore, ``__'', or single underscore, ``_'', should be avoided because are used by C and C++.

Memory Allocation

new and delete will be used for memory allocation and deletion instead of the malloc/free family of functions because, for objects, new and delete allow for destructors to clean up storage allocated by the object. In addition, the use of new and delete allows redefinition the global new and delete, ::new and ::delete. By redefining these global operators, allocation/deallocation inconsistencies can be tracked down to the source code line, with the help of the preprocessor. Thus new and delete allow for finer control of the memory allocation process for all dynamic data. (p.18 Meyers) However, this method is useful primarily for testing, and no code should be checked into the system with ::new or ::delete defined because defining these affects the whole project. Modifications to ::new or ::delete must be approved by the various member of the consortium.

Name Space Management

To avoid name space conflicts, global variables should be avoided. A better approach is to use static member variables of a class. To avoid type clashes we will use the method which was used in InterViews 4A macro will be defined,
\#define \_lib\_aips(name) aips\#\#name
which will create a token unique to the aips project. This will be generated by sed/egrep which will pull out class definitions and generate the defines for the class name. So a define will be generated for each class name, #define MyClass _lib_aips(MyClass). Thus aips scope can be entered by including a given file, aips-enter.h, and aips scope can be exited by including a different file, aips-exit.h.

Thus to enter an AIPS++ code section the programmer would include the file aips-enter.h and this file would be automatically generated from the other AIPS++ header files and might look like:

// No multiple inclusion protection to allow reentering AIPS++
//    scope in the same file, file contains only \#defines.

\#define String \_lib\_aips(String)
...MORE SIMILAR DEFINES...
Thus every time a developer referenced a member of class String the class name would be replaced with _lib_aips(String) which would expand as described above to aips##String and finally to aipsString. Then to exit the scope of aips code the developer would include file aips-exit.h which is also automatically generated. This file might look like:
\#undef String
...MORE SIMILAR UNDEFS...
Thus each reference to String would now reference a string defined possibly in some other class library. Hopefully, this sort of context switching will be the exception rather that the rule, and developers will simply include aips_enter.h at the top of a source file and not have to worry about name clashes.

In addition, the use of identifiers which begin with a double underscore, ``__'', or a single-underscore, ``_'', should be avoided. Identifiers which begin with a double underscore are reserved for C++ and those which begin with a single underscore are reserved for C.

Gotos

The use of gotos in code should be avoided. This well used standard is especially applicable in object oriented design. Gotos in code make the code much more difficult to read and violate logical scoping. (See Plum, p.126)

Switch Statements

Switch statements should be used when applicable. However, designs which rely upon switch statements based on the runtime type of objects should be avoided. Occasionally, this may be the only solution, but it should be cause of reevaluation of the design.


next up previous
Next: Guidelines Up: AIPS++ Programming Standards DRAFT Version Previous: Introduction
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15