简体   繁体   English

在不同平台上的 C 的 void* 中安全地存储类似 int 的值

[英]Safely storing an int-like value in a void* in C on different platforms

I have a simple linked list where the primary data is a void* .我有一个简单的链表,其中主要数据是void* For one bit of my program I would like to store a list of integer values.对于我的程序的一部分,我想存储 integer 值的列表。 I know GList does this using the GINT_TO_POINTER macro:我知道 GList 使用GINT_TO_POINTER宏来做到这一点:

#define GINT_TO_POINTER(v) ((gpointer)(gssize)(v))

My question is about gssize .我的问题是关于gssize This is defined in the.in file and thus I assume takes on a value during config.这是在.in 文件中定义的,因此我假设在配置期间采用一个值。 Unless I'm mistaken, this is the platform's native pointer size.除非我弄错了,否则这是平台的本机指针大小。 So is it not always going to be size_t ?那么它不总是size_t吗?

I wrote code using size_t and it ran OK, but a goal is to run on different platforms, is there a safer way of doing this?我使用size_t编写代码并且运行良好,但目标是在不同平台上运行,有没有更安全的方法?

My question is about gssize .我的问题是关于gssize This is defined in the.in file and thus I assume takes on a value during config.这是在.in 文件中定义的,因此我假设在配置期间采用一个值。 Unless I'm mistaken, this is the platform's native pointer size.除非我弄错了,否则这是平台的本机指针大小。 So is it not always going to be size_t ?那么它不总是size_t吗?

I presume you mean you think the size of gssize is the same as the platform's native pointer size.我想您的意思是您认为gssize的大小与平台的本机指针大小相同。 It cannot be the size itself (a number) because a type is required in that context.它不能是大小本身(数字),因为在该上下文中需要类型。

Even so, that exhibits some misunderstandings.即便如此,这也显示出一些误解。 The relative sizes of the types is not the fundamental consideration here, because converting values between pointer and integer types is not necessarily realized as a simple reinterpretation of part or all of the value's bit pattern.类型的相对大小不是这里的基本考虑因素,因为在指针和 integer 类型之间转换值不一定实现为对值的部分或全部位模式的简单重新解释。

For usefully encoding integer values as pointer values, you need a mechanism and constraints ensuring that you can successfully decode the pointer values back to the original integer values.为了有效地将 integer 值编码为指针值,您需要一种机制和约束来确保您可以成功地将指针值解码回原始 integer 值。 It is important to understand that standard C does not provide any mechanism certain to achieve that .了解标准 C 不提供任何机制来实现这一点很重要。

The closest it comes is the reverse: stdint.h defines types intptr_t and uintptr_t , with the property that最接近的是相反的情况: stdint.h定义类型intptr_tuintptr_t ,其属性为

any valid pointer to void can be converted to this type, then converted back to pointer to void , and the result will compare equal to the original pointer.任何指向void的有效指针都可以转换为此类型,然后转换回指向void的指针,结果将与原始指针进行比较。

(C17 7.20.1.4/1) (C17 7.20.1.4/1)

Unfortunately, that is not the guarantee you want.不幸的是,这不是您想要的保证。

I wrote code using size_t and it ran OK, but a goal is to run on different platforms, is there a safer way of doing this?我使用 size_t 编写代码并且运行良好,但目标是在不同平台上运行,有没有更安全的方法?

Although it is common for size_t to be the same type as uintptr_t , that does not have to be the case, nor do these need to have the same range (which is a different question).尽管size_tuintptr_t的类型相同是很常见的,但不一定是这种情况,也不需要具有相同的范围(这是一个不同的问题)。 Where they differ, uintptr_t would probably be the better choice for your purposes.在它们不同的地方, uintptr_t可能是您的目的的更好选择。 I anticipate that that will work as desired on many platforms, but again, there is no alternative that standard C guarantees will work portably, everywhere.我预计这将在许多平台上按预期工作,但同样,标准的 C保证将在任何地方便携工作,这是无可替代的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM