c - 对 C 结构中两个连续点的包装做出假设是否安全?

标签 c pointers struct packing

我正在研究从基于 GObject 的库到标准 ML 的语言绑定(bind)。更准确地说,我实现了对 G(S)List 集合类型的支持。此实现需要从 G(S)Lists 链接中提取数据并从标准 ML 中获取下一个链接。而不是通过 FFI 调用 G(S)List 函数之一,我希望可以使用 FFI 的指针操作函数来访问适当的结构元素以提高效率。但是,这要求可以预测结构中第二个(下一个链接)指针的偏移量。作为引用,这就是 GSList 的内容链接结构看起来像

struct GSList {
    gpointer data;
    GSList *next;
};

我认为这对任何人来说都不足为奇。可以安全地假设指向结构的指针指向它的第一个元素,即数据指针,但是第二个元素呢?我可以对第二个元素相对于第一个元素的偏移量做出任何与平台无关的假设吗?

最佳答案

It's safe to assume that the pointer to a struct points to it's first element, ie the data pointer, but how about the second element?

是的。这是安全的。 struct 对象的地址和它的第一个元素的地址保证是相同的。在结构的第一个成员之前不允许填充。

Can I make any platform independent assumptions about the offset of the second element in relation to the first?

没有。这不安全。结构的第一个和第二个元素之间可能有填充字节,任何假设都是不可移植的。但你可以使用 offsetof从结构的开头获取任何成员的偏移量。

例如,您可以将 next 的偏移量设置为:

size_t next_offset =  offsetof(struct GSList, next);

GCC 提供了一个 attribute禁用填充:

__attribute__((packed))

MSVC 也提供了类似的选项。

关于c - 对 C 结构中两个连续点的包装做出假设是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34242474/

相关文章:

c - c中的多个条件变量

c++ - 在结构中显式存储项

c - 使用变量作为结构标识符

不使用 sprintf 将无符号整数转换为十六进制字符串

c - 函数和头文件 (ansi c)

c - 使用函数填充 C 中的数组

合并内存并处理 C 中的指针运算

c++ - 在 C++ 中复制和反转 char*

c - 双向链表: Incompatible pointer types

c++ - Char 数组和 uintptr_t