ACE Implementation Guidelines

Last modified .

 

Thanks to Graham Dumpleton <grahamd@nms.otc.com.au> for providing corrections to the OSE Classtools link and description. Thanks also to Graham for providing the OSE tools!

Coding Guidelines

ACE Usage Guidelines

ACE Design Rules

Initialization on first use is preferred over using static initializations, especially when creating OO class libraries. I.e., use Double Check Locking.
This is a well known problem among OO C++ class designers. See Designing and Coding Reusable C++ by Caroll and Ellis, for example.

If you are parameterizing a searchable container template class with readers/writer locks, do not use sentinels or any state that requires updating during a a search.
....

In multi-threaded objects, all methods should be re-entrant..

Framework users should always use wrappers instead of directly making system calls.
....

Always guard against multiple inclusion of header files..

Templates may require source. Hence, source files may need to be guarded against multiple inclusion too.
Template classes should not be mixed with non-template classes..

Guard against quirky compiler implementations through #define abstractions (whereever possible)..

Use consistent error-handling..

Abstract away different representations of handles / file descriptors..

Avoid the use of global functions..

If functions are required, place them within a namespace or nested in a class..

Avoid polluting the namespace..

Don't use the inline keyword directly..

Separate inline code into their own implementation files. I.e. do not write code in header files..

(Internationalization) Do not use the char type directly. Abstract it for wide characters. Thus, do not assume your character abstraction is a single byte..

Don't use conditional compilation based on compiler/OS/hardware platform, but upon available features..

Centralize portability #ifdefs in a single place to ease portability maintainence..

Either check or return all return values (from framework calls)..

Apply strategy pattern to factor out common sources of variation in a component..

Use traits to merge multiple template arguments..

Allow customization of memory allocation.

Instrument framework methods to allow for run-time tracing.

Avoid long chains of dereference operators.

Use open() methods rather than constructors.

Instrument a dump() method in every object.

Qualify references to base class methods and data. I.e., anything outside the scope of the class.

Guard against multiple open() and close() calls, for idempotency.

The state of an object does not need to be guarded in destructors.

Base classes should not store information about derived classes.

Don't make static objects whose correctness depends on constructors being called. (That is, if 0 initialization is not sufficient.)

Guarantee singleton destruction. E.g., provide hooks that allow singletons to be deleted before the process exits.

All uses of the placement new operator must be accompanied by a corresponding explicit destructor call.

In classes that require locking, have public methods acquire the locks and call protected/private methods that do not acquire the locks.

Try to minimize the number of template parameters passed to a base class. Try to have a base class that is not a template, from which specialized classes can be derived that may have template parameters.

Define wrappers around clusters of functionality that are semantically the same but may have accidental incompatibilities. E.g., semaphores, readers/writer locks, mutex + condition variables, which can be used by threads, processes, that may or may not reside on the same machine.

Define generic components that can be parameterized by the wrappers defined above (in the previous point).

Separate creation from use. E.g., acceptor/connector and service handler.

In searchable containers, separate traversal logic from item operations.

...

CVS Usage Guidelines

Software Engineering Guidelines


Last modified: Fri Dec 5 17:29:17 CST 1997