Differences between revisions 21 and 22
Revision 21 as of 2008-02-25 16:00:56
Size: 6040
Editor: mpiat1403
Comment: Standardize your project on the use of tabs and line endings
Revision 22 as of 2008-02-25 16:21:34
Size: 6244
Editor: mpiat1403
Comment: Use native IDEs only for editing and debugging
Deletions are marked like this. Additions are marked like this.
Line 84: Line 84:

 * Use native IDEs for editing and debugging, but avoid using an IDE in place of GNU make (or some other command-line based build system) when it comes to architecting a solution to your build system.

Tips for writing portable code

Many useful tips are taken from the book [http://proquest.safaribooksonline.com/9780321246424 Cross-Platform Development in C++: Building Mac OS X, Linux, and Windows Applications] by Syd Logan. This book describe the essential best practices of a cross-platform development culture that was adopted companywide within Netscape, and embraced by Mozilla, which was critical in enabling Netscape and Mozilla to ship product with approximately the same level of quality across a wide spectrum of platforms to tens of millions of users.

Coding

  • Use the -ansi and -pedantic-errors or comparable compiler options.

  • Use typedefs for integer types whenever the integer must be of a definite size. For example, define and use the type INT32 for integers that must consist of exactly 32 bits on all target platforms.

  • C and C++ do not specify whether the char data type is signed or unsigned. This can be a problem when mixing char and int types in code — the classic example is reading characters from stdin in C into a unsigned char using the getchar() function, which returns an int and typically uses –1 to indicate end of file. If you mix char and int types, explicitly declare the char as signed or unsigned.
  • Use the C and C++ Standard Library (part of which is the STL) whenever possible.

  • Standardize your project on the use of tabs and line endings so that the formatting the programmer intended is reproduced faithfully, regardless of the editor one uses. Configure the editor to expand tabs into spaces, with two to four spaces per tab. Ensure that lines of text end with newlines (LF). On Linux and Mac OS X, this is the default. Visual Studio also uses this as a default, but not all editors do. When installing Cygwin, make sure to choose the UNIX line endings option when prompted.

Compiler warnings

Pay attention to compiler warnings; they tell you about uncertainty: that the code the compiler is generating on your behalf may lead to undefined or incorrect behavior at runtime. When other platforms are added to the mix, this uncertainty takes on another dimension because each platform may deal with the warned issue in different ways at runtime, which leads to a near certainty that the code causing the compiler warning will not be portable.

  • With g++, the following flags create useful warnings: -Wall, - Werror, -std=c++98, -pedantic-errors.
  • With Microsoft Visual C++, the following flags create useful warnings (roughly analogous to those listed above): /Wn, /Wall, /Wx, /Za

Do not think that if you build your code using g++, along with the compiler flags listed above, then you do not need to enable the corresponding flags for Visual C++ since g++ already has issued all relevant warnings. It is even likely that code that would lead to the issuance of warnings by one compiler will be missed by another compiler.

Policy and management

  • Make all of your platforms a priority from the very beginning on: To do cross-platform software well, parity, both in terms of functionality and quality, must be fully met on all the supported platforms, at all phases of the product's development and release. Perhaps the scariest situation one can face in cross-platform development is this question: "Now that we have it working on platform x, what about getting it to work on platform y?"
  • Code from a common codebase: When code cannot be shared, it should be hidden behind abstractions that provide a unified application programming interface (API). Applications using the abstract API should do so ignorant that the API is abstracting platform-specific functionality. The [http://en.wikipedia.org/wiki/Abstract_factory_pattern Abstract Factory Pattern] may be very useful here.

  • Organize the project in your repository. Example layout:

lib
   lib1
         mac
                include
                debug
                release
         win
                include
                debug
                release
         linux
                include
                debug
                release
   lib2
         [...]
src
   component1
          src
               mac
               win
               linux
          inc
               mac
               win
               linux
   component2
          [...]
   main
  • Require developers to compile their code with different compilers. This can be done on a single platform (building with Microsoft Visual C++ and Borland C++, for example), or by building using different compilers available on other platforms.
    1. It helps you to avoid the use of compiler-specific features, flags, and macros.
    2. It minimizes the impact of various interpretations of C/C++ standards, and helps you avoid using unproven language features.
    3. Each compiler will produce different sets of warnings and errors, which makes development easier, and strengthens the code that you write.
    4. Different compilers generate different code, which can illuminate problems you might otherwise not detect.
  • Require developers to build and smoke test their code on all platforms before they check it into the repository. (A smoke test is the first test made after changes to provide some assurance that the system under test will not catastrophically fail.)
  • Test builds on each supported platform in regular intervals: Close the repository for normal check-ins, do the smoke tests on each platform. If a problem is detected and fixed, make a special check-in to the repository to resolve the issue. If all problems are resolved, reopen the repository for normal check-ins.

Build system and toolchain

  • Use whatever compiler makes the most sense for a platform. On Windows, this typically means using Visual C++, and GNU g++ on Mac OS X and Linux. In order to produce cross-platform code, you need not standardize all your platforms upon a single toolchain.
  • Use native IDEs for editing and debugging, but avoid using an IDE in place of GNU make (or some other command-line based build system) when it comes to architecting a solution to your build system.

CompleteSearch: completesearch/WritingPortableCode (last edited 2008-10-23 11:40:12 by mpiat1403)