工会内的位域对齐 [英] Alignment of bitfields inside unions

查看:190
本文介绍了工会内的位域对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  struct Thing 
我有点困惑于下面的代码如何在内存中放置: {
union
{
无符号值:24;
uint8_t bytes [3];
};
Thing(int v)
:value(v)
{}
$ b void foo()
{
printf(Thing% p值=%d!\ n,this,value);
}

} __attribute __((__ packed__));

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

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

我们在这里有一些类似的代码, :24在一个结构中,并且有人加入了联合并且无意中将结构的大小从3增加到了4字节。
如果我试图将联合定义为packed - 大小仍然是4,那么会发生同样的事情。这种行为是否符合C ++规范?会有什么解释?

稍后编辑:用C ++规范替换C规范。

解决方案

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

pre $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $# } PACKED;
struct S2 {union {char a [3];无符号值:24; }; } PACKED;
struct S3 {union {char a [3];无符号值: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

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


I'm a bit puzzled by how the following code gets layed out in memory:

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__));

On gcc 3.3, 4.3 or 4.6 on Linux (without any special options I can think of - only "-Wall -g" on 4.6), the size of the structure is always 4:

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

We had some similar code here where we had the unsigned value:24 in a structure, and somebody added the union and inadvertently increased the size of the struct from 3 to 4 bytes. The same thing happens if I try to define the union as "packed" - size is still 4. Is this behavior as per the C++ spec? What would be the explanation?

later edit: replaced "C spec" with "C++ spec".

解决方案

You missed the packed attributes to your anonymous union. Consider this example:

#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;
}

Output:

3
4
3

The packed attribute is a little weird, I always try and test every possible combination to get proper result.

这篇关于工会内的位域对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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