问题描述
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 :: cout<< sizeof(S2)<< std :: cout<< sizeof(S3)}
输出:
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.
这篇关于工会内的位域对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!