Developing For Portability

                       Avoiding The Seven Deadly Sins

Willows Software has identified the top seven implementation practices which
lead to poor portability of applications. These are summarized below. Once
your software adheres to this principles, use The Willows Toolkit to port
the application, using the same source tree, to UNIX, Mac and other systems.

1. Compiler Issues

To ensure portable code, avoid using compiler specificfeatures which are not
ANSI C/C++ standard. Microsoft compilers provide a significant number of
these features. Each compiler feature should be researched to determine
whether or not it is supported by ANSI C/C++ standard compilers.

Examples of non-portable features:

   * Pragma statements
   * Warning levels
   * Model size specifications such as smalland large
   * Platform specific compiler extensions such as near,far and huge.

To make these non-portable features portable,use a platform-specific header
file to isolate the platform dependencies.

DOS files have a carriage return and line feed at the end of each line and a
control-Z at the end of the last line in source files. These may have to be
removed on some platforms,and can usually be converted during the transfer
(e.g., use ASCII mode in ftp, not binary).

Microsoft compilers support the use of "//"in order to separate comments
from code in the source code. Thisis not supported by ANSI C, although it is
supported by ANSI C++.Use "/*" and "*/" to enclose a comment for ANSI C
standard compliance.

2. Coding Conventions

Hard-coded constants should not be used - use #defineinstead. For example,
pointer sizes may be different on different platforms and the assumption
should not be made that an intcan be used to contain the pointer.

Function prototypes should be used to define functions before they are
referenced in the source code. This will force the compiler to emit the
correct code for arguments and return values. If this is not done, the
compiler will use argument and return value size defaults which will be
different for different platforms.

Use typedef to declare an identifier as a name for a type before it is
referenced in the code. By being so explicit, the compiler does not have to
make any assumptions regarding type sizes. For application specific objects
that must be a precise size, create a complete set of unique typedefs. These
application-specific data types and structures can be modified, minimally
affecting the source code that uses these data types.

3. Data Structure Padding

Never assume offset sizes in data structures. Different compilers pack and
size structures differently. The best way to handle this is to use a macro
wherever possible to ensure that the correct byte alignment will be
achieved. To eliminate alignment and packing issues, avoid casting a memory
location for a specific structure member or component, or for a location
within the structure member itself. Also, use the sizeof operator when
referencing the size of a structure. Do not use hard-coded constant
valuesfor sizes.

4. Big/Little Endian

Binary data may not have the same byte-order as the platform on which the
program is running. A portable set of routines or macros may be used to
extract data by byte-swapping as necessary.

5. Portable File Formats

Files containing binary data are often an area of portability problems. The
file may contain size and/or offset information which is appropriate on one
platform but not on another due to data type size changes and structure
packing.

For example, a structure within a data file may have been written on a
platform where pointer or integer sizes are different from the target
platform. This data can no longer be read directly into a memory data
structure as the offsets and sizes will be different. Each element of the
structure will have to be read into memory individually, processed and then
placed into the memory data structure. This processing will also have to
address any byte-ordering differences between the platforms.

6. Platform-Specific Filenames

Any use of embedded filenames must be examined for the inclusion of path
separation characters and for upper and lower case letters. An example of
this is in #include directives. Any filename contained within quotes or
angle-brackets may be platform specific. To minimize portability problems,
avoid theuse of full or partial paths. Put only the filename itself within""
or <>.

7. Run Time Issues

It is a good idea to use libraries that are suppliedon the target platform
to access platform specific features. In addition, moving references to
these features to a separate sourcefile as a prelude to determining how to
handle the features is recommended.

Conclusion: Willows Software Inc. develops cross-platform tools and
middleware for porting Windows applications to UNIX, Macintosh, real-time
operating systems and other environments. By avoiding the Seven Deadly Sins,
you will develop applications which can be ported to a wide variety of
platforms using The Willows Toolkit.

----------------------------------------------------------------------------

                                 Back to Top

----------------------------------------------------------------------------

Copyright © The Canopy Group. All rights reserved.
Revised: May 1, 1997

Information in this document is subject to change without notice.

Other products and companies referred to herein are trademarks or registered
trademarks of their respective companies or mark holders.