是否有与指针大小相同的整数类型?在所有微体系结构上都保证吗?
u
) intptr_t
,并再次转换回来(前提是其所引用的内存仍然有效),并且一个空指针会转换为0。在“合理”的体系结构中,它只是一个内存地址,但这并不是绝对有保障的(例如,强制类型转换可能会随机排列比特,不能保证您可以从 uintptr_t
的表示中推断对齐方式,指针算术运算不需要工作……)。 - tc.int x = 0; if ((void*)x) { ... }
是具有实现定义的。但如果编译器决定某些内容不再是常量时,行为发生剧变的想法确实很奇怪。 - tc.typedef struct {
int isPointer;
union {
int intVal;
void *ptrVal;
}
} myType;
然后您可以使用isPointer 'boolean'来决定是否将联合体视为整数或指针。
编辑:
如果执行速度非常重要,则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
unsigned char *dummy = malloc (4);
void *special_value1 = dummy + 0;
....
这将使特殊值保留在L1d缓存中,而不是L1i中,但我认为我可以接受这种方式。 - martin#ifdef DEVMODE
宏中,以便不影响生产代码。 - paxdiabloC99标准定义了标准的整数类型:
7.18.1.4 可以容纳对象指针的整数类型 以下类型指定了一种带有如下属性的有符号整数类型:任何有效的void指针都可以转换为该类型,然后再转换回void指针,并且结果将与原始指针比较相等:
intptr_t
以下类型表示一个无符号整数类型,具有这样的属性:任何有效的指向void的指针都可以转换为该类型,然后再转换回void指针,结果将与原始指针相等。 uintptr_t
这些类型是可选的。
C99还定义了size_t和ptrdiff_t:
这些类型是
ptrdiff_t
这是两个指针相减的结果所得到的带符号整数类型。
size_t
size_t
是sizeof运算符结果的无符号整数类型;而我所见过的架构中,对象的最大大小等于整个内存,因此sizeof(size_t)
==sizeof(void*)
,但我不知道有什么东西既可以移植到C89(size_t
是),又保证足够大(uintptr_t
是)。
在标准的32位系统上,这是正确的,但并没有任何保证,并且可能会发现有很多架构不是这样。例如,一个常见的误解是在x86_64上sizeof(int)应该是8(因为它是一个64位系统),但实际上不是。在x86_64上,sizeof(int)仍然是4,但sizeof(void*)是8。
这个问题的标准解决方案是编写一个小程序,检查所有int类型(short int,int,long int)的大小,并将它们与void*进行比较。如果匹配,则发出一段代码来定义intptr类型。您可以将此放入头文件中并使用新类型。
将此代码包含在构建过程中很简单(例如使用make
)。
不。
我不相信C标准甚至规定了标准整数大小。再加上所有的架构(8/16/32/64位等),就没有任何保证。
在大多数架构上,int数据类型将是答案。
但对于任何(微)架构都没有保证。
int
通常是32位的,因此在某些情况下,您可能更想使用long
。 - Magnus Hoffunion int_ptr_t {
int i;
void* p;
};