【问题标题】:Redundant __packed__ attributes冗余 __packed__ 属性
【发布时间】:2010-08-26 01:27:21
【问题描述】:

此代码适用于 Microchip 的 PIC32MX 微处理器。他们的编译器本质上是 GCC 3.4。

我倾向于使用 GCC 的__packed__ attribute 将位域打包到一个联合中,然后将它们作为unsigned char(即类型双关语)检索以通过 SPI 或 I2C 发送。这种行为都是由我的实现定义的,并且运行良好。我更喜欢这个而不是一百行左右的掩蔽和移位:)

我的问题是:下面的代码中有__packed__ 属性是多余的吗?乍一看,我认为工会高层成员可以免去,但我不太确定。或者我可以省略嵌套结构中的那些吗?

// Remember that bitfields cannot straddle word boundaries!
typedef struct
{
    /// Some flag #1
    unsigned FlagOne            : 1 __attribute__((packed));
    /// Some flag #2
    unsigned FlagTwo            : 1 __attribute__((packed));
    /// A chunk of data
    unsigned SomeData           : 5 __attribute__((packed));

    // and so on, maybe up to 32 bits long depending on the destination

} BlobForSomeChip;

/// This kind of type-punning is implementation defined. Read Appendix A (A7, A12) of
/// the MPLAB C Compiler for PIC32 MCUs manual.
typedef union
{
    /// Access the members of this union to set flags, etc
    BlobForSomeChip blobdata __attribute__((packed));

    /// As a byte for sending via SPI, I2C etc
    unsigned char bytes[4] __attribute__((packed));

} BlobData;

【问题讨论】:

    标签: c gcc bit-fields type-punning


    【解决方案1】:

    首先,我推荐使用-Wall编译。

    现在:

    1. BlobForSomeChip 结构声明了 7 位。通常,由于对齐,它的长度为 4 个字节,但使用打包属性时,它只有 1 个字节长。
    2. 无法打包unsigned char[4]。无论如何,它总是 4 个字节长。

    简而言之:

    1. struct BlobForSomeChip = 1 个字节
    2. unsigned char[4] = 4 个字节
    3. BlobData = 4 字节(其最大成员的大小)。

    最后,BlobData 上的打包属性不是必需的。如果使用 GCC 将简单地忽略它们 - 使用 -Wall 查看输出。

    【讨论】:

    • 对于上面的第 1 点 - // and so on 评论意味着它可以是长达 32 位的任何内容。我通常会用未命名的位域填充 8 位倍数以外的任何内容。因此,还要考虑BlobForSomeChip 正好是 32 位的情况(但我认为你的解释也应该适用)。
    • @detly:正确,以字节为单位的大小始终为 ceil(总位数 / 8)。打包属性仅删除填充/对齐。 N 显式/声明位将始终为 N 位。
    • -Wall 在 GCC 3.4 上似乎没有发现这一点(至少在 MC 的编译器中)。我将检查 Debian 打包版本。但除此之外,很好的解释,谢谢:)
    • 哦,为了完整起见,如果我的位域结构 is 不完整(即
    • @detly:对不起,我没有注意你提到的编译器版本。这可能是正确的,我猜只有 GCC>=4.1 会检查这个,我的错。至于最后一条评论,工会成员之间没有对齐,因为所有成员都从同一个地址开始 - 工会地址。而且由于没有填充,它的大小总是与其最大的成员大小相匹配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    • 2019-06-08
    相关资源
    最近更新 更多