$(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) ) )