使用intptr_t而不是void *?
使用intptr_t
作为通用存储(保存指针和整数值)而不是void*
是一个好主意吗? (如下所示: http : //www.crystalspace3d.org/docs/online/manual/Api1_005f0-64_002dBit-Portability-Changes.html )
对于我已经读过的内容:
-
int
– >void*
– >int
roundtrip不保证保持原始值; 我猜int
– >intptr_t
– >int
会做 -
void*
和intptr_t
上的指针算术需要强制转换,所以没有人在这里获得优势 -
void*
表示存储指针时显式转换次数较少,intptr_t
表示存储整数值时转换次数较少 -
intptr_t
需要C99
还有什么我应该考虑的?
使用
intptr_t
作为通用存储(保存指针和整数值)而不是void*
是一个好主意吗?
没有。
intptr_t
不保证存在。 首先,正如您所说,它是在C99中引入的。 其次,实现不需要具有足够大的整数类型来保持转换的指针值而不丢失信息。
将int
转换为intptr_t
并返回不太可能丢失信息,但实际上并没有保证intptr_t
比int
更宽。
如果要存储指针值,请将它们存储在指针对象中。 这就是指针对象的用途。
任何指向对象或不完整类型的指针都可以转换为void*
并再次返回而不会丢失信息。 对指向函数的指针没有这样的保证 – 但是任何指向函数的指针都可以转换为任何其他指向函数类型的指针而不会丢失信息。 (我指的是C标准;我认为POSIX提供了一些额外的保证。)
如果要在同一对象中存储整数或指针值,首先应该重新考虑您的设计。 如果你已经这样做,并得出结论你确实想要这样做,可以考虑使用联合(并仔细跟踪你最近存储的是什么类型的值)。
有些API使用void*
参数来允许传递任意数据; 例如,参见POSIX pthread_create()
函数。 这可以通过将整数值转换为void*
来滥用,但是传递整数对象的地址会更安全。
不,你不能保证任何特定类型是存储指针和整数的合理方式,此外,它会使你的代码混乱。 有一个更好的办法。
如果要在同一对象中存储整数和指针,则干净且可移植的方法是使用union:
union foo { int integer_foo; void *pointer_foo; }
这是便携式的,允许您以两者中较大者所需的存储大小存储两种物品。 保证始终有效。