29

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

我还应该考虑什么?

4

2 回答 2

32

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

不。

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

来回转换int不太可能丢失信息,但没有比 . 更宽的实际保证。intptr_tintptr_tint

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

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

如果你想在同一个对象中存储一个整数或一个指针值,你应该做的第一件事是重新考虑你的设计。如果您已经这样做了,并得出结论认为您确实想要这样做,请考虑使用联合(并仔细跟踪您最近存储的值类型)。

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

于 2012-02-29T02:47:00.233 回答
7

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

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

union foo {
   int integer_foo;
   void *pointer_foo;
};

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

于 2012-02-29T03:04:53.760 回答