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.