Sizes of data types
The 32- and 64-bit versions of QNX Neutrino use different C Language Data Type Models:
- 32-bit uses ILP32: integers, long integers, and pointers are 32 bits long.
- 64-bit uses LP64: long integers and pointers are 64 bits long.
The sizes of the basic data types are as follows:
| Data type | 32-bit | 64-bit |
|---|---|---|
| char | 8 | 8 |
| int | 32 | 32 |
| long | 32 | 64a |
| long long | 64 | 64 |
| off_t | signed 32 | signed 64 |
| paddr_t | unsigned 32 | unsigned 64 |
| ptrdiff_t | 32 | 64 |
| short | 16 | 16 |
| size_t, ssize_t | 32 | 64 |
| time_t | unsigned 32 | signed 64 |
| uintptr_t, intptr_t | 32 | 64 |
| void * | 32 | 64 |
a 64-bit Windows uses 32 bits for a long because there's a lot of code that assumes that a long and an int are the same size. 64-bit Unix-type OSs use 64 bits for a long.
The sizes of many compound types depend on the architecture. These include the following:
- struct sigevent
- union sigval
- siginfo_t
- struct iovec
- struct utimbuf
- struct sigaction
- struct _timer_info
- struct timeval
- and anything else that includes a base type whose size varies
When we extended the structures, we defined additional versions for 32- and 64-bits. For example, in addition to struct sigevent, we've defined struct __sigevent32 and struct __sigevent64 that have the correctly sized fields. These additional types let you access—for example—the 32-bit structure in a program compiled for 64 bits. The fields might not be of the same type as in the original structure, but they'll be the correct size.
Because of all these differences, you need to be careful with data types. For example:
- NULL is now defined as (void *) 0 instead of just 0, so it no longer fits in an int or char. Don't use NULL as the terminating character in a string.
- int and unsigned can't hold pointers or pointer differences in 64-bit architectures. Use uintptr_t to cast pointers to an integer type.
- Use size_t or ptrdiff_t to hold the result of subtracting one pointer from another.
pointer & ~unsignedmasks out more bits than you might expect. Usepointer & ~uintptr_tinstead.
You can use the PRI* macros that are defined in <inttypes.h> to simplify calls to printf() that involve integers whose conversion specifier is different in 32- and 64-bit architectures.
