我有一个指针。在32位系统上,它是32位。在64位系统上,它是64位。
我有一个很长的整数字段用作标识符,有时我想在那里使用指针值。 (我从来没有回到指针 - 一旦我将它转换为整数字段,我只是将它与相等进行比较)。
在32位和64位系统上,这样做似乎是安全的。 (在较大的指针系统上不是这样)。这是真的吗?
然后,有没有办法让GCC仅在建立安全的平台(目前是所有目标平台)时才发出以下警告?
错误:从不同大小的整数转换为指针[-Werror = int-to-pointer-cast]
答案 0 :(得分:10)
根据标准,无法保证指针适合整数类型。实际上,在大多数个人计算机上,存在多个memory models。您可以看到指针和整数类型的大小并不总是相同(即使在“常规”计算机上)。
您应该使用C99中的可选类型intptr_t
和uintptr_t
。
C11(n1570),§7.20.1.4
以下类型指定带有任何有效属性的有符号整数类型 指向
void
的指针可以转换为此类型,然后转换回指向void
的指针, 并且结果将与原始指针进行比较:intptr_t
。以下类型指定无符号整数类型,其属性为any 指向
void
的指针可以转换为此类型,然后转换回指向void
的指针, 并且结果将与原始指针进行比较:uintptr_t
。
这是一个小例子:
#include <stdio.h>
#include <stdint.h>
int n = 42;
int *p = &n;
intptr_t i = (intptr_t)(void *)p;
int *q = (void *)i;
printf("%d\n", *q);
答案 1 :(得分:1)
如果您想要一个保证大到足以容纳指针的整数类型,请考虑intptr_t
(已签名)或uintptr_t
。该标准保证这些数据类型足以容纳指针。没有别的假设,尤其不是long int
足够长。