root/trunk/docsrc/32-64-portability.dd

Revision 2334, 3.4 kB (checked in by walter, 1 year ago)

add portability guide

Line 
1 Ddoc
2
3 $(SPEC_S $(TITLE),
4
5     $(P Although D is designed to make it easy to port code between
6     32 and 64 bit modes, being a systems programming language,
7     dependencies can creep in. This guide points out what changes
8     between the two.
9     )
10
11 $(SECTION2 Versions,
12     $(P Not all code can be made portable between 32 and 64 bits,
13     and must be versioned. The following works:
14     )
15
16 ---
17 version (X86)
18     ... 32 bit code ...
19 else version (X86_64)
20     ... 64 bit code ...
21 else
22     static assert("unsupported target")
23 ---
24
25     $(P It is best to write versioning in that manner to give a compile
26     time error on a new target, rather than guessing in advance what, for example,
27     a 64 bit ARM target might require.
28     Experience shows that guesses about how an unfamiliar platform might work
29     always get it wrong.
30     Save those decisions for when one is actually working on a 64 bit ARM.
31     )
32 )
33
34 $(SECTION2 Size Changes,
35
36     $(P The size of pointers and references will increase from 4
37     to 8 bytes. The $(TT size_t) alias moves from $(TT uint) to
38     $(TT ulong), and the $(TT ptrdiff_t) alias moves from $(TT int)
39     to $(TT long).
40     )
41
42     $(P The sizes of compound types based on these will also increase.
43     This includes dynamic arrays, associative arrays, delegates,
44     and class references.
45     )
46 )
47
48 $(SECTION2 Structs,
49
50     $(P The size of the struct and the alignment of its fields
51     will change, in order to match the C ABI of the equivalent
52     C struct.
53     )
54 )
55
56 $(SECTION2 Classes,
57
58     $(P The size of the class and the alignment of its fields
59     will change, in order to match the alignment most suitable
60     for the 64 bit mode, and in order to accommodate the increased
61     size of pointers and references.
62     )
63 )
64
65 $(SECTION2 printf,
66
67     $(P Since $(TT printf) is a C function, it follows C typing rules.
68     This can have consequences for using them with D types.
69     )
70
71     $(TABLE1
72     $(TR <th rowspan=2>D Type</th> <th colspan=2>printf format</th>)
73     $(TR $(TH 32 bit) $(TH 64 bit))
74     $(TR $(TD $(I T)*) $(TD %p) $(TD %p))
75     $(TR $(TD long) $(TD %lld) $(TD %d))
76     $(TR $(TD ulong) $(TD %llu) $(TD %u))
77     $(TR $(TD ptrdiff_t) $(TD %td) $(TD %td))
78     $(TR $(TD size_t) $(TD %zu) $(TD %zu))
79     )
80
81     $(P For 32 bit code, it was common to use the $(TT %.*s) format
82     to print strings. This relied on the 32 bit C ABI interpreting the
83     components of a dynamic array as separate length and pointer arguments.
84     64 bit parameter passing is different, and so the length and pointer
85     should be done explicitly:
86     )
87
88 ---
89 string s;
90 ...
91 printf("s = '%.*s'\n", s);               // 32 bit only
92 printf("s = '%.*s'\n", s.length, s.ptr); // 32 and 64 bit
93 ---
94 )
95
96 $(SECTION2 Inline Assembly,
97
98     $(P Naturally, inline assembly for 32 bit code won't work for 64 bit code.
99     The versioning statements to use are:
100     )
101
102 ---
103 version (D_InlineAsm_X86)
104     ... 32 bit assembler ...
105 version (D_InlineAsm_X86_64)
106     ... 64 bit assembler ...
107 else
108     static assert("unsupported target");
109 ---
110
111     $(P The 64 bit inline assembler uses the syntax found in the Intel
112     and AMD instruction set references.
113     )
114 )
115
116 $(SECTION2 Variadic Arguments,
117
118     $(P How variadic arguments work in 64 bits is radically different from
119     32 bits. They are not a simple array on the stack. You will need to use
120     the functions and templates in $(TT std.c.stdarg) to access them.
121     )
122
123 )
124
125 )
126
127 Macros:
128     TITLE=Porting 32 Bit Code to 64 Bits
129     WIKI=32To64
Note: See TracBrowser for help on using the browser.