| 1 |
Ddoc |
|---|
| 2 |
|
|---|
| 3 |
$(SPEC_S Portability Guide, |
|---|
| 4 |
|
|---|
| 5 |
$(P It's good software engineering practice to minimize gratuitous |
|---|
| 6 |
portability problems in the code. |
|---|
| 7 |
Techniques to minimize potential portability problems are: |
|---|
| 8 |
) |
|---|
| 9 |
|
|---|
| 10 |
$(UL |
|---|
| 11 |
|
|---|
| 12 |
$(LI The integral and floating type sizes should be considered as |
|---|
| 13 |
minimums. |
|---|
| 14 |
Algorithms should be designed to continue to work properly if the |
|---|
| 15 |
type size increases.) |
|---|
| 16 |
|
|---|
| 17 |
$(LI Floating point computations can be carried out at a higher |
|---|
| 18 |
precision than the size of the floating point variable can hold. |
|---|
| 19 |
Floating point algorithms should continue to work properly if |
|---|
| 20 |
precision is arbitrarily increased.) |
|---|
| 21 |
|
|---|
| 22 |
$(LI Avoid depending on the order of side effects in a computation |
|---|
| 23 |
that may get reordered by the compiler. For example: |
|---|
| 24 |
|
|---|
| 25 |
------- |
|---|
| 26 |
a + b + c |
|---|
| 27 |
------- |
|---|
| 28 |
|
|---|
| 29 |
$(P can be evaluated as (a + b) + c, a + (b + c), (a + c) + b, (c + b) + a, |
|---|
| 30 |
etc. Parentheses control operator precedence, parentheses do not |
|---|
| 31 |
control order of evaluation. |
|---|
| 32 |
) |
|---|
| 33 |
|
|---|
| 34 |
$(P Function parameters can be evaluated either left to right |
|---|
| 35 |
or right to left, depending on the particular calling conventions |
|---|
| 36 |
used. |
|---|
| 37 |
) |
|---|
| 38 |
|
|---|
| 39 |
$(P If the operands of an associative operator + or * are floating |
|---|
| 40 |
point values, the expression is not reordered. |
|---|
| 41 |
) |
|---|
| 42 |
) |
|---|
| 43 |
|
|---|
| 44 |
$(LI Avoid dependence on byte order; i.e. whether the CPU |
|---|
| 45 |
is big-endian or little-endian.) |
|---|
| 46 |
|
|---|
| 47 |
$(LI Avoid dependence on the size of a pointer or reference being |
|---|
| 48 |
the same size as a particular integral type.) |
|---|
| 49 |
|
|---|
| 50 |
$(LI If size dependencies are inevitable, put an $(TT assert) in |
|---|
| 51 |
the code to verify it: |
|---|
| 52 |
|
|---|
| 53 |
------- |
|---|
| 54 |
assert(int.sizeof == (int*).sizeof); |
|---|
| 55 |
------- |
|---|
| 56 |
) |
|---|
| 57 |
) |
|---|
| 58 |
|
|---|
| 59 |
<h2>32 to 64 Bit Portability</h2> |
|---|
| 60 |
|
|---|
| 61 |
$(P 64 bit processors and operating systems are here. |
|---|
| 62 |
With that in mind: |
|---|
| 63 |
) |
|---|
| 64 |
|
|---|
| 65 |
$(UL |
|---|
| 66 |
|
|---|
| 67 |
$(LI Integral types will remain the same sizes between |
|---|
| 68 |
32 and 64 bit code.) |
|---|
| 69 |
|
|---|
| 70 |
$(LI Pointers and object references will increase in size |
|---|
| 71 |
from 4 bytes to 8 bytes going from 32 to 64 bit code.) |
|---|
| 72 |
|
|---|
| 73 |
$(LI Use $(B size_t) as an alias for an unsigned integral |
|---|
| 74 |
type that can span the address space. |
|---|
| 75 |
Array indices should be of type $(B size_t).) |
|---|
| 76 |
|
|---|
| 77 |
$(LI Use $(B ptrdiff_t) as an alias for a signed integral |
|---|
| 78 |
type that can span the address space. |
|---|
| 79 |
A type representing the difference between two pointers |
|---|
| 80 |
should be of type $(B ptrdiff_t).) |
|---|
| 81 |
|
|---|
| 82 |
$(LI The $(B .length), $(B .size), $(B .sizeof), $(B .offsetof) |
|---|
| 83 |
and $(B .alignof) |
|---|
| 84 |
properties will be of type $(B size_t).) |
|---|
| 85 |
|
|---|
| 86 |
) |
|---|
| 87 |
|
|---|
| 88 |
<h2>Endianness</h2> |
|---|
| 89 |
|
|---|
| 90 |
$(P Endianness refers to the order in which multibyte types |
|---|
| 91 |
are stored. The two main orders are $(I big endian) and |
|---|
| 92 |
$(I little endian). |
|---|
| 93 |
The compiler predefines the version identifier |
|---|
| 94 |
$(B BigEndian) or $(B LittleEndian) depending on the order |
|---|
| 95 |
of the target system. |
|---|
| 96 |
The x86 systems are all little endian. |
|---|
| 97 |
) |
|---|
| 98 |
|
|---|
| 99 |
$(P The times when endianness matters are:) |
|---|
| 100 |
|
|---|
| 101 |
$(UL |
|---|
| 102 |
$(LI When reading data from an external source (like a file) |
|---|
| 103 |
written in a different |
|---|
| 104 |
endian format.) |
|---|
| 105 |
$(LI When reading or writing individual bytes of a multibyte |
|---|
| 106 |
type like $(B long)s or $(B double)s.) |
|---|
| 107 |
) |
|---|
| 108 |
|
|---|
| 109 |
<h2>OS Specific Code</h2> |
|---|
| 110 |
|
|---|
| 111 |
$(P System specific code is handled by isolating the differences into |
|---|
| 112 |
separate modules. At compile time, the correct system specific |
|---|
| 113 |
module is imported. |
|---|
| 114 |
) |
|---|
| 115 |
|
|---|
| 116 |
$(P Minor differences can be handled by constant defined in a system |
|---|
| 117 |
specific import, and then using that constant in an |
|---|
| 118 |
$(I IfStatement) or $(I StaticIfStatement). |
|---|
| 119 |
) |
|---|
| 120 |
) |
|---|
| 121 |
|
|---|
| 122 |
Macros: |
|---|
| 123 |
TITLE=Portability |
|---|
| 124 |
WIKI=Portability |
|---|