ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

C联盟成员访问和未定义的行为

2019-07-31 01:05:15  阅读:215  来源: 互联网

标签:c undefined-behavior unions


我目前正在开展一个项目,其中提供了以下内容
结构法.我的工作是C,但该项目同时使用C和C.结构相同
定义由C和C使用.

typedef struct PacketHeader {
    //Byte 0
    uint8_t  bRes                           :4;
    uint8_t  bEmpty                         :1;
    uint8_t  bWait                          :1;
    uint8_t  bErr                           :1;
    uint8_t  bEnable                        :1;
    //Byte 1
    uint8_t  bInst                          :4;
    uint8_t  bCount                         :3;
    uint8_t  bRres                          :1;
    //Bytes 2, 3
    union {
        uint16_t wId;    /* Needed for Endian swapping */
        struct{
            uint16_t wMake                  :4;
            uint16_t wMod                   :12;
        };
    };
} PacketHeader;

取决于结构的实例的使用方式,所需的字节顺序
结构可以是大端或小端.作为前两个字节的
结构是每个单个字节,这些不需要在字节序时改变
变化.
存储为单个uint16_t的字节2和3是我们需要的唯一字节
交换以实现所需的字节顺序.为了实现字节顺序交换,我们有
一直在执行以下操作:

//Returns a constructed instance of PacketHeader with relevant fields set and the provided counter value
PacketHeader myHeader = mmt::BuildPacketHeader(count);

uint16_t packetIdFlipped;
//Swap positions of byte 2 and 3
packetIdFlipped = myHeader.wId << 8;
packetIdFlipped |= (uint16_t)myHeader.wId >> 8;

myHeader.wId = packetIdFlipped;

函数BuildPacketHeader(uint8_t)为成员wMake和赋值
wMod显式,并且不写入成员wId.我的问题是关于
从返回的实例中的成员wId读取的安全性
结构体.

诸如此类的问题
Accessing inactive union member and undefined behavior?,
Purpose of Unions in C and C++,
Section 10.4 of the draft standard I have分别提到了在C中访问一个非活动成员所引起的未定义行为.

链接草案第10.4节中的第1段也包含以下注释,但我不确定我是否理解所使用的所有术语:

[Note: One special guarantee is made in order to simplify the use of unions: If a standard-layout union contains several standard-layout structs that share a common initial sequence (10.3), and if a non-static datamember of an object of this standard-layout union type is active and is one of the standard-layout structs, itis permitted to inspect the common initial sequence of any of the standard-layout struct members; see 10.3.— end note]

正在读取packetIdFlipped = myHeader.wId<<行中的myHeader.wId 8未定义的行为? 未命名的结构是活动成员,因为它是函数调用中写入的最后一个成员吗? 或者注释是否意味着访问wId成员是安全的,因为它和struct共享一个共同的类型? (这是普通初始序列的意思吗?) 提前致谢

解决方法:

The function BuildPacketHeader(uint8_t) assigns values to the members
wMake and wMod explicitly, and does not write to the member wId. My
question is regarding the safety of reading from the member wId inside
the returned instance of the structure.

是的,这是UB.这并不意味着它不起作用,只是它可能不起作用.您可以在BuildPacketHeader中使用memcpy来避免这种情况(参见thisthis).

标签:c,undefined-behavior,unions
来源: https://codeday.me/bug/20190731/1585699.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有