【问题标题】:Access same variable with 2 different dimension using Unions使用联合访问具有 2 个不同维度的相同变量
【发布时间】:2025-12-30 01:55:07
【问题描述】:

我必须解决以下问题:我正在使用这个结构之王来访问相同的变量但大小不同。

typedef struct {
        union {
            struct {
                uint16 progressNumber;
            };
            uint8 progressNumberArr[2];
        };
} ProgressNum_t;
ProgressNum_t totalProgressiveNumber;

通过这种方式,我可以访问一个 8 位数组(它对 SPI 通信很有用),也可以管理一个 16 位变量。在我的情况下,它是一个计数器,我必须管理溢出等等......

此过程运行良好,但对于 MISRA 规则,我不允许使用它(因为行为可能未定义)。

您有什么建议可以使用相同的“技巧”但符合 MISRA?

【问题讨论】:

  • 你应该使用stdint.h而不是一些自制的味道。

标签: c unions misra type-punning


【解决方案1】:

这是一条建议性规则 - 您需要详细阅读规则 19.2。它带有例外。

此代码的行为未定义,并且像这样的类型双关语 - 使用uint8_t 之类的字符类型进行序列化/反序列化 - 是联合的有效用途之一。与例如通过union 创建“变体”类型不同,这是非常值得怀疑的做法。

此 MISRA 规则背后最重要的理由是,同一内存区域绝不应用于不相关目的。在您的示例中不是这种情况,每个联合成员都引用具有相同二进制表示的相同数据。

然而,代码是依赖于字节序的。如 19.2 中所述,您需要在偏离规则时同时考虑填充/对齐和字节序。

如果您希望严格遵循 MISRA-C,那么您可以放弃联合,声明一个普通的 uint16_t 并使用位移位来屏蔽 MS 字节和 LS 字节。这样,无论字节顺序如何,代码也变得可移植。

【讨论】:

    【解决方案2】:

    除了 Lundin 的回答,该规则是为了防止你做所有 unions 允许你做的坏事......但因为它是 咨询,它允许你使用union 关键字在哪里这样做是安全的,最小的大惊小怪(即没有正式的偏差)

    但如果您确实使用union,请确保您了解自己在做什么......

    元素的联合与 unsigned char 数组配对通常是可以的 - 只要您注意实现定义的可移植性问题(例如字节序)

    -- 查看隶属关系的个人资料

    【讨论】:

      最近更新 更多