简体   繁体   English

如何正确访问打包的结构成员

[英]How to properly access packed struct members

What is the correct way to access packed struct's members?访问打包结构成员的正确方法是什么?

struct __attribute__ ((packed)) MyData {
    char ch;
    int i;
}
void g(int *x); // do something with x

void foo(MyData m) {
    g(&m.i);
}

void bar(MyData m) {
    int x = m.i;
    g(&x);
}

My IDE gives warning/suggestion for foo that I might be accessing misaligned int pointer, which is indeed the case here.我的 IDE 为 foo 发出警告/建议,我可能正在访问未对齐的 int 指针,这确实是这种情况。 My questions are我的问题是

  • Between foo and bar, is one approach better than the other?在 foo 和 bar 之间,一种方法比另一种更好吗?
  • Is it incorrect to access misaligned pointer data but okay to use it to initialize a properly aligned type?访问未对齐的指针数据是否不正确,但可以使用它来初始化正确对齐的类型? (as in bar). (如酒吧)。
  • Should we copy packed struct individual members to properly aligned data structure and then use it?我们是否应该将打包的 struct 单个成员复制到正确对齐的数据结构中,然后使用它? That would imply that for almost every packed data structure there is a non-packed data structure and packed structure remains confined to serialization layer.这意味着几乎每个打包数据结构都有一个非打包数据结构,而打包结构仍然局限于序列化层。

Is it incorrect to access misaligned pointer data but okay to use it to initialize a properly aligned type?访问未对齐的指针数据是否不正确,但可以使用它来初始化正确对齐的类型? (as in bar). (如酒吧)。

As far as the C++ language is concerned, there is no such thing as a packed class nor such thing as improperly aligned object.就 C++ 语言而言,没有打包的 class 之类的东西,也没有对齐不正确的 object 之类的东西。 Hence, an improperly aligned pointer would necessarily be invalid.因此,不正确对齐的指针必然是无效的。

Whether your compiler that provides a language extension for packed classes also extends the language to allow access through misaligned pointers is up for your compiler vendor to document.为打包类提供语言扩展的编译器是否也扩展了语言以允许通过未对齐的指针进行访问,这取决于您的编译器供应商来记录。 The warning implies that latter extension might not be supported.该警告意味着可能不支持后一种扩展。

Between foo and bar, is one approach better than the other?在 foo 和 bar 之间,一种方法比另一种更好吗?

bar , as per the warning. bar ,根据警告。

Should we copy packed struct individual members to properly aligned data structure and then use it?我们是否应该将打包的 struct 单个成员复制到正确对齐的数据结构中,然后使用它? That would imply that for almost every packed data structure there is a non-packed data structure and packed structure remains confined to serialization layer.这意味着几乎每个打包数据结构都有一个非打包数据结构,而打包结构仍然局限于序列化层。

That could be a convenient solution to confine the non-standard packed classes into the serialisation layer.这可能是将非标准打包类限制在序列化层中的便捷解决方案。

Note that this isn't the only problem with packed structs.请注意,这不是打包结构的唯一问题。 Another problem is portability of serialised data between systems due to different byte orders and sizes of types.另一个问题是由于不同的字节顺序和类型大小,系统之间的序列化数据的可移植性。

A portable way to serialise data is to not use packed structs at all, but rather shift bytes individually using explicit offsets.序列化数据的一种可移植方法是根本不使用打包结构,而是使用显式偏移单独移动字节。

Currently, calling g may assume that x is aligned.目前,调用g可能假设x是对齐的。 This will probably be fine on x86 architectures, but foo might crash on ARM.这在 x86 架构上可能没问题,但foo可能会在 ARM 上崩溃。

Calling it like in bar is not much better than g taking int x .像在bar中那样调用它并不比gint x好多少。 However, it is correct, since the compiler knows that mi is misaligned, so can generate the code to copy a misaligned int.但是,这是正确的,因为编译器知道mi未对齐,因此可以生成代码来复制未对齐的 int。 This does mean that the pointer can't modify the original object (unless you reassign it).这确实意味着指针不能修改原来的 object(除非你重新分配它)。

You can also use the type of a misaligned integer:您还可以使用未对齐的 integer 的类型:

typedef int __attribute__((aligned(1))) packed_int;
void g(packed_int * x); // do something with x

This can be called directly as g(&m.i) .这可以直接称为g(&m.i) Be warned that it cannot perform aligned access leading to slowdowns on some platforms.请注意,它无法执行对齐的访问,从而导致某些平台上的速度变慢。

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

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