Ddoc $(SPEC_S Portability Guide, $(P It's good software engineering practice to minimize gratuitous portability problems in the code. Techniques to minimize potential portability problems are: ) $(UL $(LI The integral and floating type sizes should be considered as minimums. Algorithms should be designed to continue to work properly if the type size increases.) $(LI Floating point computations can be carried out at a higher precision than the size of the floating point variable can hold. Floating point algorithms should continue to work properly if precision is arbitrarily increased.) $(LI Avoid depending on the order of side effects in a computation that may get reordered by the compiler. For example: ------- a + b + c ------- $(P can be evaluated as (a + b) + c, a + (b + c), (a + c) + b, (c + b) + a, etc. Parentheses control operator precedence, parentheses do not control order of evaluation. ) $(P Function parameters can be evaluated either left to right or right to left, depending on the particular calling conventions used. ) $(P If the operands of an associative operator + or * are floating point values, the expression is not reordered. ) ) $(LI Avoid dependence on byte order; i.e. whether the CPU is big-endian or little-endian.) $(LI Avoid dependence on the size of a pointer or reference being the same size as a particular integral type.) $(LI If size dependencies are inevitable, put an $(TT assert) in the code to verify it: ------- assert(int.sizeof == (int*).sizeof); ------- ) )

32 to 64 Bit Portability

$(P 64 bit processors and operating systems are here. With that in mind: ) $(UL $(LI Integral types will remain the same sizes between 32 and 64 bit code.) $(LI Pointers and object references will increase in size from 4 bytes to 8 bytes going from 32 to 64 bit code.) $(LI Use $(B size_t) as an alias for an unsigned integral type that can span the address space. Array indices should be of type $(B size_t).) $(LI Use $(B ptrdiff_t) as an alias for a signed integral type that can span the address space. A type representing the difference between two pointers should be of type $(B ptrdiff_t).) $(LI The $(B .length), $(B .size), $(B .sizeof), $(B .offsetof) and $(B .alignof) properties will be of type $(B size_t).) )

Endianness

$(P Endianness refers to the order in which multibyte types are stored. The two main orders are $(I big endian) and $(I little endian). The compiler predefines the version identifier $(B BigEndian) or $(B LittleEndian) depending on the order of the target system. The x86 systems are all little endian. ) $(P The times when endianness matters are:) $(UL $(LI When reading data from an external source (like a file) written in a different endian format.) $(LI When reading or writing individual bytes of a multibyte type like $(B long)s or $(B double)s.) )

OS Specific Code

$(P System specific code is handled by isolating the differences into separate modules. At compile time, the correct system specific module is imported. ) $(P Minor differences can be handled by constant defined in a system specific import, and then using that constant in an $(I IfStatement) or $(I StaticIfStatement). ) ) Macros: TITLE=Portability WIKI=Portability