void *
)? Якщо на 32-бітних системах розмір вказівника рівний розміру типу даних int
, то в 64-бітних системах усе залежить від реалізації. Наприклад, тип int
може бути як 32-бітним (Microsoft Win64, більшість UNIX-подібних систем), так і 64-бітним (якщо система використовує модель даних ILP64 або SILP64). Аналогічна ситуація і з типом long
: він 64-бітний на більшості систем, проте є системи, де його розмірність рівна 32 біт. Детальніше про це можна прочитати тут:http://en.wikipedia.org/wiki/64-bit#Specific_C-language_data_models.
Отже, задача звелася до того, що слід мати універсальний тип даних, розмірність якого завжди відповідає розмірності вказівника. Як виявилося, в UNIX-подібних системах існують спеціальні типи даних, спроектовані для операцій з вказівниками, такі як
ptrdiff_t
, intptr_t
, uintptr_t
.Тип
ptrdiff_t
призначений зберігання результатів віднімання вказівників і є знаковим.Тип
intptr_t
є його синонімом.Тип
uintptr_t
є беззнаковим цілочисельним типом і здатен безпечно зберігати у собі вказівник незалежно від розрядності платформи.Отже, для моєї задачі потрібен був тип
uintptr_t
. Слід було лише виявити, для якої платформи який заголовний файл (header) слід включити, щоб використати цей тип.Ось список заголовних файлів відповідно для системи:
GNU/Linux | - stdint.h; |
Solaris | - inttypes.h; |
AIX | - inttypes.h; |
IRIX | - додадковий заголовний файл не потрібен; |
HP-UX | - sys/wsio.h. |
Відповідно, універсальний код для включення типу
uintptr_t
:
#if defined(__hpux)
#include <sys/wsio.h>
#else
# if defined(__sun) || defined(_AIX)
#include <inttypes.h>
# else
# ifndef __sgi
#include <stdint.h>
# endif
# endif
#endif