如何覆盖 C 编译器将结构中的字大小变量对齐到字边界 [英] How to override C compiler aligning word-sized variable in struct to word boundary

查看:41
本文介绍了如何覆盖 C 编译器将结构中的字大小变量对齐到字边界的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个指定如下的结构

I have a structure specified as following

  • 成员 1,16 位
  • 成员 2,32 位
  • 成员 3,32 位

我将从文件中读取.我想直接从文件读入结构.

which I shall be reading from a file. I want to read straight from the file into the struct.

问题是 C 编译器会将变量 m1、m2 和 m3 与 32 位的字边界对齐,因为我正在为以下结构声明使用 ARM Cortex M3:

The problem is that the C compiler will align the variables m1, m2 and m3 to word boundaries which are at 32 bits since I am working on an ARM Cortex M3 for the following struct declaration:

typedef struct
{
    uint16_t m1;
    uint32_t m2;
    uint32_t m3;
}something;

直接从文件中读取会在 m2 和 m3 中放置错误的值,并且也会读取 2 个额外的字节.

Reading directly from file will put wrong values in m2 and m3, and reads 2 extra bytes too.

我已经破解了,目前正在使用以下效果很好的方法:

I have hacked around and am currently using the following which works just fine:

typedef struct
{
    uint16_t m1;
    struct
    {
        uint16_t lo;
        uint16_t hi;
    }m2;
    struct
    {
        uint16_t lo;
        uint16_t hi;
    }m3;
}something;

然而,这看起来像一个非常肮脏的黑客.我不禁希望有一种更简洁的方法来强制编译器将 m2 和 m3 的一半放在不同的词中,无论它可能是次优的.

However, this looks like a really dirty hack. I cannot help wishing for a cleaner way to force the compiler to put halves of m2 and m3 in different words, however sub-optimal it may be.

我正在使用 arm-none-eabi-gcc.我了解位打包,但无法解决此优化问题.

I am using arm-none-eabi-gcc. I know about bit packing, but am unable to work around this optimisation.

结果我对位打包了解得不够 :D

推荐答案

您正在寻找的是 packed 属性.这将强制 gcc 在成员周围不做任何填充.摘自 GCC 在线文档:

What you are looking for is the packed attribute. This will force gcc to not do any padding around members. Taken from the GCC Online docs:

打包

此属性附加到枚举、结构或联合类型定义,指定用于表示类型所需的最小内存.为 struct 和 union 类型指定此属性等效于在每个结构或联合成员上指定打包属性.在行上指定 -fshort-enums 标志等效于在所有枚举定义上指定打包属性.

This attribute, attached to an enum, struct, or union type definition, specified that the minimum required memory be used to represent the type. Specifying this attribute for struct and union types is equivalent to specifying the packed attribute on each of the structure or union members. Specifying the -fshort-enums flag on the line is equivalent to specifying the packed attribute on all enum definitions.

您只能在枚举定义的右花括号之后指定该属性,而不能在 typedef 声明中指定,除非该声明还包含枚举的定义.

You may only specify this attribute after a closing curly brace on an enum definition, not in a typedef declaration, unless that declaration also contains the definition of the enum.

所以你想要的是:

typedef struct
{
    uint16_t m1;
    uint32_t m2;
    uint32_t m3;
} __attribute__ ((packed)) something;

此外,我建议使用编译时断言检查以确保结构的大小确实符合您的需求想要它.

In addition I would recommend using a compile time assertion check to ensure that the size of the struct is really what you want it to be.

这篇关于如何覆盖 C 编译器将结构中的字大小变量对齐到字边界的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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