[英]Safely storing an int-like value in a void* in C on different platforms
我有一个简单的链表,其中主要数据是void*
。 对于我的程序的一部分,我想存储 integer 值的列表。 我知道 GList 使用GINT_TO_POINTER
宏来做到这一点:
#define GINT_TO_POINTER(v) ((gpointer)(gssize)(v))
我的问题是关于gssize
。 这是在.in 文件中定义的,因此我假设在配置期间采用一个值。 除非我弄错了,否则这是平台的本机指针大小。 那么它不总是size_t
吗?
我使用size_t
编写代码并且运行良好,但目标是在不同平台上运行,有没有更安全的方法?
我的问题是关于
gssize
。 这是在.in 文件中定义的,因此我假设在配置期间采用一个值。 除非我弄错了,否则这是平台的本机指针大小。 那么它不总是size_t
吗?
我想您的意思是您认为gssize
的大小与平台的本机指针大小相同。 它不能是大小本身(数字),因为在该上下文中需要类型。
即便如此,这也显示出一些误解。 类型的相对大小不是这里的基本考虑因素,因为在指针和 integer 类型之间转换值不一定实现为对值的部分或全部位模式的简单重新解释。
为了有效地将 integer 值编码为指针值,您需要一种机制和约束来确保您可以成功地将指针值解码回原始 integer 值。 了解标准 C 不提供任何机制来实现这一点很重要。
最接近的是相反的情况: stdint.h
定义类型intptr_t
和uintptr_t
,其属性为
任何指向
void
的有效指针都可以转换为此类型,然后转换回指向void
的指针,结果将与原始指针进行比较。
(C17 7.20.1.4/1)
不幸的是,这不是您想要的保证。
我使用 size_t 编写代码并且运行良好,但目标是在不同平台上运行,有没有更安全的方法?
尽管size_t
与uintptr_t
的类型相同是很常见的,但不一定是这种情况,也不需要具有相同的范围(这是一个不同的问题)。 在它们不同的地方, uintptr_t
可能是您的目的的更好选择。 我预计这将在许多平台上按预期工作,但同样,标准的 C保证将在任何地方便携工作,这是无可替代的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.