forked from dlang/dlang.org
-
Notifications
You must be signed in to change notification settings - Fork 0
/
portability.dd
121 lines (90 loc) · 3.14 KB
/
portability.dd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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 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 $(D assert) in
the code to verify it:
-------
assert(int.sizeof == (int*).sizeof);
-------
)
)
$(H2 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 $(D size_t) as an alias for an unsigned integral
type that can span the address space.
Array indices should be of type $(D size_t).)
$(LI Use $(D 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 $(D ptrdiff_t).)
$(LI The $(D .length), $(D .size), $(D .sizeof), $(D .offsetof)
and $(D .alignof)
properties will be of type $(D size_t).)
)
$(H2 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
$(D BigEndian) or $(D 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 $(D long)s or $(D double)s.)
)
$(H2 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
CATEGORY_SPEC=$0