$(DDOC $(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
$(SPEC_S Portability Guide,
$(DDOC_BLANKLINE )
$(HEADERNAV_TOC $(HEADERNAV_ITEM 32_to_64bit, 32 to 64 Bit Portability)
$(HEADERNAV_ITEM endianness, Endianness)
$(HEADERNAV_ITEM os_specific_code, OS Specific Code)
)
$(DDOC_BLANKLINE )
$(P It's good software engineering practice to minimize gratuitous
portability problems in the code.
Techniques to minimize potential portability problems are:
)
$(DDOC_BLANKLINE )
$(UL $(DDOC_BLANKLINE )
$(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.)
$(DDOC_BLANKLINE )
$(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.)
$(DDOC_BLANKLINE )
$(LI Avoid depending on the order of side effects in a computation
that may get reordered by the compiler. For example:
$(DDOC_BLANKLINE )
$(D_CODE a + b + c
)
$(DDOC_BLANKLINE )
$(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.
)
$(DDOC_BLANKLINE )
$(P If the operands of an associative operator + or * are floating
point values, the expression is not reordered.
)
)
$(DDOC_BLANKLINE )
$(LI Avoid dependence on byte order; i.e. whether the CPU
is big-endian or little-endian.)
$(DDOC_BLANKLINE )
$(LI Avoid dependence on the size of a pointer or reference being
the same size as a particular integral type.)
$(DDOC_BLANKLINE )
$(LI If size dependencies are inevitable, put a $(D static assert) in
the code to verify it:
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD static) $(D_KEYWORD assert)($(D_KEYWORD int).sizeof == ($(D_KEYWORD int)*).sizeof);
)
)
)
$(DDOC_BLANKLINE )
$(LNAME2 32_to_64bit, 32 to 64 Bit Portability)
$(DDOC_BLANKLINE )
$(P 32 bit processors and operating systems are still out there.
With that in mind:
)
$(DDOC_BLANKLINE )
$(UL $(DDOC_BLANKLINE )
$(LI Integral types will remain the same sizes between
32 and 64 bit code.)
$(DDOC_BLANKLINE )
$(LI Pointers and object references will increase in size
from 4 bytes to 8 bytes going from 32 to 64 bit code.)
$(DDOC_BLANKLINE )
$(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).)
$(DDOC_BLANKLINE )
$(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).)
$(DDOC_BLANKLINE )
$(LI The $(D .length), $(D .size), $(D .sizeof), $(D .offsetof)
and $(D .alignof)
properties will be of type $(D size_t).)
$(DDOC_BLANKLINE )
)
$(DDOC_BLANKLINE )
$(LNAME2 endianness, Endianness)
$(DDOC_BLANKLINE )
$(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.
)
$(DDOC_BLANKLINE )
$(P The times when endianness matters are:)
$(DDOC_BLANKLINE )
$(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.)
)
$(DDOC_BLANKLINE )
$(LNAME2 os_specific_code, OS Specific Code)
$(DDOC_BLANKLINE )
$(P System specific code is handled by isolating the differences into
separate modules. At compile time, the correct system specific
module is imported.
)
$(DDOC_BLANKLINE )
$(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).
)
$(SPEC_SUBNAV_PREV_NEXT objc_interface, Interfacing to Objective-C, entity, Named Character Entities)
)
)