使用intptr_t而不是void *?

时间:2012-02-29 02:32:22

标签: c pointers 32bit-64bit void-pointers intptr

使用intptr_t作为通用存储(保存指针和整数值)而不是void*是一个好主意吗? (如下所示:http://www.crystalspace3d.org/docs/online/manual/Api1_005f0-64_002dBit-Portability-Changes.html

对于我已经读过的内容:

  • int - > void* - > int往返不保证保持原始价值;我想int - > intptr_t - > int会做
  • void*intptr_t上的指针算术需要强制转换,所以没有人在这里获得优势
  • void*表示存储指针时显式投射较少,intptr_t表示存储整数值时投射较少
  • intptr_t需要C99

我还应该考虑什么?

2 个答案:

答案 0 :(得分:29)

  

使用intptr_t作为通用存储(保存指针和整数值)而不是void*是不是一个好主意?

没有

intptr_t不保证存在。首先,正如您所说,它是在C99中引入的。其次,实现不需要具有足够大的整数类型来保存转换的指针值而不会丢失信息。

int转换为intptr_t并返回不太可能以丢失信息,但没有实际保证intptr_t宽于int

如果要存储指针值,请将它们存储在指针对象中。这就是指针对象的用途。

任何指向对象或不完整类型的指针都可以转换为void*并再次返回,而不会丢失信息。指向函数的指针没有这样的保证 - 但是任何指向函数的指针都可以转换为任何其他指向函数类型的指针而不会丢失信息。 (我指的是C标准;我认为POSIX提供了一些额外的保证。)

如果要在同一对象中存储整数或指针值,首先应该重新考虑您的设计。如果您已经这样做了,并且认为您确实想要这样做,请考虑使用联合(并仔细跟踪您最近存储的值)。

有些API使用void*参数来允许传递任意数据;例如,参见POSIX pthread_create()函数。这可以通过将整数值强制转换为void*来滥用,但传递整数对象的地址会更安全。

答案 1 :(得分:5)

不,不能保证任何特定类型都是存储指针和整数的合理方式,此外,它会使您的代码混乱。还有更好的方法。

如果要在同一个对象中存储整数和指针,那么干净且可移植的方法是使用联合:

union foo {
   int integer_foo;
   void *pointer_foo;
}

这是便携式的,允许您以两者中较大者所需的存储大小存储两种物品。保证始终有效。