THE NEED FOR WRITING PORTABLE CODE
1) Size of native types & memory models : In C++ standards, no specific maximums are specified for types, but rather than this there are minimum values. Instead practically , those maximums are specified by memory models chosen by platforms :
(Regarding the models : I stands for integer, L for long and P for pointer )
Below you can see which memory models are used by operating systems :
32 bit Windows systems : ILP32
32 bit Unix & Linux systems : ILP32
64 bit Windows systems : LLP64
64 bit Unix & Linux systems : LP64
2) 32 bit vs 64 bit : As known, CPU architecture specifies a word size which is also size of a register and typically sizeof(int) in most compiler and operating systems.
However beyond size of types, there are more considerations about CPU architecture ( 32 bit or 64 bit ) :
- 2a) 32 bit address space can map 4 GB system memory. Whereas 64 bit can go up to 2^64 bytes memory. This needs to be taken into consideration. For example this would help software suffering from paging in operating system level since more memory can be used.
- 2b) On windows systems and Linux systems, you will need to port your DLLs/shared objects to target systems, as 32 bit and 64 bit address spaces in both systems are isolated.On Windows the typical error message you will get is “Can`t find the file” and in Linux you will get “wrong ELF class” error.
- 2c) You might need to consider to gain speed by using 64-bit registers.
- 2d) When you compile for 64 bit, the C++ compilers can make the assumption that SSE instructions are available so they can produce code that runs faster
3) Endianness : Little endian and big endian is a well known topic. A typical port example for this one :
Previous generation game consoles like Xbox360 and PS3 used to use PowerPC processors which were Big Endian.
And since PCs use Little Endian architecture, texture output systems used in video game industry were platform specific, therefore they were reverting bytes when necessary.
1) std::size_t : In C++ standards, std::size_t is guaranteed to store the largest object`s size. Also by STL , it is used to store size of objects. Therefore it can be used also for portability.
2) std::ptrdiff_t : This type is used for calculating distance between memory locations pointed by two different pointers. This gives a portable way to do memory operations.
3) climits.h : This header can be used to determine range of types which could be used to avoid overflows/underflows :
4) cstdint.h and cinttypes.h : Both headers gives fixed size types such as int8_t and so on. The difference between two is that , inttypes.h also support functions like printf and scanf :
Developers of famous C++ static analysis tool PVS studio has an article series on development for programming for 64 bit systems :