加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 联合内部的位域对齐

发布时间:2020-12-16 07:01:20 所属栏目:百科 来源:网络整理
导读:我对以下代码如何在内存中布局感到困惑: struct Thing{ union { unsigned value:24; uint8_t bytes[3]; }; Thing(int v) :value(v) {} void foo() { printf("Thing %p value=%d !n",this,value); }} __attribute__((__packed__)); 在Linux上的gcc 3.3,4.3
我对以下代码如何在内存中布局感到困惑:

struct Thing
{
    union
    {
        unsigned value:24;
        uint8_t bytes[3];
    };
    Thing(int v)
            :value(v)
    {}

    void foo()
    {
        printf("Thing %p value=%d !n",this,value);
    }

} __attribute__((__packed__));

在Linux上的gcc 3.3,4.3或4.6上(没有我能想到的任何特殊选项 – 在4.6上只有“-Wall -g”),结构的大小总是4:

$pahole ./union
struct Thing {
        union {
                unsigned int               value;                /*           4 */
                unsigned char              bytes[3];             /*           3 */
        };
[...]

我们在这里有一些类似的代码,其中我们有无符号值:结构中有24个,有人添加了联合,并且无意中将结构的大小从3增加到4个字节.
如果我尝试将union定义为“packed”,同样的事情会发生 – size仍然是4.这个行为是否符合C规范?会有什么解释?

稍后编辑:将“C spec”替换为“C spec”.

解决方法

您错过了匿名联盟的打包属性.考虑这个例子:

#define PACKED __attribute__((__packed__))
struct S1 { unsigned value:24; } PACKED ;
struct S2 { union { char a[3]; unsigned value:24; };  } PACKED ;
struct S3 { union { char a[3]; unsigned value:24; } PACKED ;  };


int main() {
   std::cout << sizeof(S1) << std::endl;
   std::cout << sizeof(S2) << std::endl;
   std::cout << sizeof(S3) << std::endl;
}

输出:

3
4
3

打包属性有点奇怪,我总是尝试测试每个可能的组合以获得正确的结果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读