The collector uses a large amount of conditional compilation in order to
deal with platform dependencies.  This violates a number of known coding
standards.  On the other hand, it seems to be the only practical way to
support this many platforms without excessive code duplication. 

A few guidelines have mostly been followed in order to keep this manageable:

1) #if and #ifdef directives are properly indented whenever easily possible.
All known C compilers allow whitespace between the "#" and the "if" to make
this possible.  ANSI C also allows white space before the "#", though we
avoid that.  It has the known disadvantages that it differs from the normal
GNU conventions, and that it makes patches larger than otherwise necessary.
In my opinion, it's still well worth it, for the same reason that we indent
ordinary "if" statements.

2) Whenever possible, tests are performed on the macros defined in gcconfig.h
instead of directly testing patform-specific predefined macros.  This makes it
relatively easy to adapt to new compilers with a different set of predefined
macros.  Currently these macros generally identify platforms instead of
features.  In many cases, this is a mistake.

3) The code currently avoids #elif, eventhough that would make it more
readable.  This was done since #elif would need to be understood by ALL
compilers used to build the collector, and that hasn't always been the case.
It makes sense to reconsider this decision at some point, since #elif has been
standardized at least since 1989.

Many of the tested configuration macros are at least somewhat defined in
either include/private/gcconfig.h or in Makefile.direct.  Here is an attempt
at defining some of the remainder:  (Thanks to Walter Bright for suggesting
this.  This is a work in progress)

MACRO		EXPLANATION
-----		-----------

__DMC__	Always #define'd by the Digital Mars compiler. Expands
		to the compiler version number in hex, i.e. 0x810 is
		version 8.1b0

_ENABLE_ARRAYNEW
		#define'd by the Digital Mars C++ compiler when
		operator new[] and delete[] are separately
		overloadable. Used in gc_cpp.h.

_MSC_VER	Expands to the Visual C++ compiler version.  Assumed to
		not be defined for other compilers (at least if they behave
		appreciably differently).

_DLL		Defined by Visual C++ if dynamic libraries are being built
		or used.  Used to test whether __declspec(dllimport) or
		__declspec(dllexport) needs to be added to declarations
		to support the case in which the collector is in a dll.

GC_DLL		User-settable macro that forces the effect of _DLL.

GC_NOT_DLL	User-settable macro that overrides _DLL, e.g. if dynamic
		libraries are used, but the collector is in a static library.

__STDC__	Assumed to be defined only by compilers that understand
		prototypes and other C89 features.  Its value is generally
		not used, since we are fine with most nonconforming extensions.

SUNOS5SIGS	Solaris-like signal handling.  This is probably misnamed,
		since it really doesn't guarantee much more than Posix.
		Currently set only for Solaris2.X, HPUX, and DRSNX.  Should
		probably be set for some other platforms.

PCR		Set if the collector is being built as part of the Xerox
		Portable Common Runtime.

SRC_M3		Set if the collector is being built as a replacement of the
		one in the DEC/Compaq SRC Modula-3 runtime.  I suspect this
		was last used around 1994, and no doubt broke a long time ago.
		It's there primarily incase someone wants to port to a similar
		system.