Проще говоря, нет. Не гарантируется для всех архитектур.
Мой вопрос: почему? Если вы хотите выделить достаточно большой тип для хранения void*
, лучше всего выделить (как ни удивительно :-) a void*
. Почему необходимо установить его в пределах int
?
РЕДАКТИРОВАТЬ: Исходя из ваших комментариев к дублирующемуся вопросу, вы хотите сохранить специальные значения указателя (1,2,3) для указания дополнительной информации.
NO !! Не делай этого !! . Нет никакой гарантии, что 1, 2 и 3 не являются абсолютно правильными указателями. Это может иметь место в системах, где требуется выравнивание указателей на 4-байтовых границах, но, поскольку вы спросили обо всех архитектурах, я предполагаю, что у вас высокая переносимость.
Найдите другой способ сделать это правильно. Например, используйте объединение (синтаксис из памяти может быть неправильным):
typedef struct {
int isPointer;
union {
int intVal;
void *ptrVal;
}
} myType;
Затем вы можете использовать isPointer 'boolean', чтобы решить, следует ли вам рассматривать объединение как целое число или указатель.
EDIT:
Если скорость выполнения имеет первостепенное значение, то решение typedef - это путь. По сути, вам нужно определить целое число, которое вы хотите для каждой платформы, на которой вы хотите работать. Вы можете сделать это с помощью условной компиляции. Я также добавил бы проверку во время выполнения, чтобы убедиться, что вы правильно скомпилировали для каждой платформы (я определяю это в исходном коде, но вы бы передали это как флаг компилятора, например "cc -DPTRINT_INT
"):
#include <stdio.h>
#define PTRINT_SHORT
#ifdef PTRINT_SHORT
typedef short ptrint;
#endif
#ifdef PTRINT_INT
typedef int ptrint;
#endif
#ifdef PTRINT_LONG
typedef long ptrint;
#endif
#ifdef PTRINT_LONGLONG
typedef long long ptrint;
#endif
int main(void) {
if (sizeof(ptrint) != sizeof(void*)) {
printf ("ERROR: ptrint doesn't match void* for this platform.\n");
printf (" sizeof(void* ) = %d\n", sizeof(void*));
printf (" sizeof(ptrint ) = %d\n", sizeof(ptrint));
printf (" =================\n");
printf (" sizeof(void* ) = %d\n", sizeof(void*));
printf (" sizeof(short ) = %d\n", sizeof(short));
printf (" sizeof(int ) = %d\n", sizeof(int));
printf (" sizeof(long ) = %d\n", sizeof(long));
printf (" sizeof(long long) = %d\n", sizeof(long long));
return 1;
}
/* rest of your code here */
return 0;
}
В моей системе (Ubuntu 8.04, 32-разрядная версия) я получаю:
ERROR: ptrint typedef doesn't match void* for this platform.
sizeof(void* ) = 4
sizeof(ptrint ) = 2
=================
sizeof(short ) = 2
sizeof(int ) = 4
sizeof(long ) = 4
sizeof(long long) = 8
В этом случае я бы знал, что мне нужно скомпилировать с PTRINT_INT (или long). Может быть способ поймать это во время компиляции с #if, но я не мог потрудиться исследовать это в данный момент. Если вы наткнетесь на платформу, где нет целочисленного типа, достаточного для удержания указателя, вам не повезло.
Имейте в виду, что использование специальных значений указателей (1,2,3) для представления целых чисел также может работать не на всех платформах - это могут быть действительные адреса памяти для указателей.
И все же, если ты собираешься игнорировать мой совет, я мало что могу сделать, чтобы остановить тебя. В конце концов, это твой код :-). Одна возможность - проверить все ваши возвращаемые значения из malloc и, если вы получите 1, 2 или 3, просто снова malloc (то есть, иметь mymalloc (), которая делает это автоматически). Это будет небольшая утечка памяти, но она не будет конфликтовать между вашими специальными указателями и реальными указателями.