gcc 结构中的内存对齐 [英] memory alignment within gcc structs

查看:28
本文介绍了gcc 结构中的内存对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将一个应用程序移植到 C 语言的 ARM 平台上,该应用程序也在 x86 处理器上运行,并且必须向后兼容.

我现在在变量对齐方面遇到了一些问题.我已经阅读了 gcc 手册__attribute__((aligned(4),packed)) 我将所说的解释为结构的开头与 4 字节边界对齐,并且由于打包语句,内部保持不变.>

最初我有这个,但偶尔它会与 4 字节边界不对齐.

typedef 结构体{无符号整数代码;无符号整数长度;无符号整数序列;无符号整数请求;无符号字符随机数[16];无符号短CRC;__attribute__((packed)) 挑战;

所以我把它改成这个.

typedef 结构体{无符号整数代码;无符号整数长度;无符号整数序列;无符号整数请求;无符号字符随机数[16];无符号短CRC;} __attribute__((aligned(4),packed)) 挑战;

我之前所说的理解似乎是不正确的,因为结构现在对齐到 4 字节边界,并且内部数据现在对齐到四字节边界,但是由于字节序,结构的大小大小从 42 字节增加到 44 字节.这个大小很关键,因为我们有其他依赖于 42 字节结构的应用程序.

有人可以向我描述如何执行我需要的操作.非常感谢任何帮助.

解决方案

如果您依赖 sizeof(yourstruct) 为 42 字节,那么您将被一个非-便携式假设.您还没有说明这是为了什么,但结构内容的字节顺序似乎也很重要,因此您也可能与那里的 x86 不匹配.

在这种情况下,我认为唯一可靠的应对方法是在重要的部分使用 unsigned char[42].首先编写一个精确的规范,说明在这个 42 字节块中的确切位置以及字节序,然后使用该定义编写一些代码以在该定义和您可以与之交互的结构之间进行转换.代码可能是一次性序列化代码(也称为编组),或者是一堆 getter 和 setter.

I am porting an application to an ARM platform in C, the application also runs on an x86 processor, and must be backward compatible.

I am now having some issues with variable alignment. I have read the gcc manual for __attribute__((aligned(4),packed)) I interpret what is being said as the start of the struct is aligned to the 4 byte boundry and the inside remains untouched because of the packed statement.

originally I had this but occasionally it gets placed unaligned with the 4 byte boundary.

typedef struct  
{  
 unsigned int code;  
 unsigned int length;  
 unsigned int seq;  
 unsigned int request;  
 unsigned char nonce[16];  
 unsigned short  crc;  
} __attribute__((packed)) CHALLENGE;

so I change it to this.

typedef struct  
{  
 unsigned int code;  
 unsigned int length;  
 unsigned int seq;  
 unsigned int request;  
 unsigned char nonce[16];  
 unsigned short  crc;  
} __attribute__((aligned(4),packed)) CHALLENGE;

The understand I stated earlier seems to be incorrect as both the struct is now aligned to a 4 byte boundary, and and the inside data is now aligned to a four byte boundary, but because of the endianess, the size of the struct has increased in size from 42 to 44 bytes. This size is critical as we have other applications that depend on the struct being 42 bytes.

Could some describe to me how to perform the operation that I require. Any help is much appreciated.

解决方案

If you're depending on sizeof(yourstruct) being 42 bytes, you're about to be bitten by a world of non-portable assumptions. You haven't said what this is for, but it seems likely that the endianness of the struct contents matters as well, so you may also have a mismatch with the x86 there too.

In this situation I think the only sure-fire way to cope is to use unsigned char[42] in the parts where it matters. Start by writing a precise specification of exactly what fields are where in this 42-byte block, and what endian, then use that definition to write some code to translate between that and a struct you can interact with. The code will likely be either all-at-once serialisation code (aka marshalling), or a bunch of getters and setters.

这篇关于gcc 结构中的内存对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆