我对以下代码如何在内存中布局感到有点困惑:
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 字节。
如果我尝试将联合定义为“打包”,也会发生同样的事情 - 大小仍然是 4。这种行为是否符合 C++ 规范?该怎么解释呢?
稍后编辑:将“C 规范”替换为“C++ 规范”。
您错过了匿名联合的打包属性。考虑这个例子:
#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
打包属性有点奇怪,我总是尝试测试每种可能的组合以获得正确的结果。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)