我知道在C中,struct成员的顺序是它们被声明的顺序加上(通常,除非另有说明),可能会出现填充,导致我创建的两个第一个结构具有各自的大小:
struct MyStructV1
{
int a;
char c;
int b;
};
printf("size of MyStructV1 is:%lu \n",sizeof(struct MyStructV1)); // prints 12
struct MyStructV1Packed
{
int a;
char c;
int b;
}__attribute__((__packed__));;
printf("size of MyStructV1Packed is:%lu \n",sizeof(struct MyStructV1Packed)); // prints 9
到目前为止一切顺利。
那么,我的问题是,MyStructV2的“解压缩”版本的以下声明是否比MyStructV1的第一个版本有任何好处/优势?
struct MyStructV2
{
int a;
int b;
char c;
};
printf("size of MyStructV2 is:%lu \n",sizeof(struct MyStructV2)); // prints 12 as well
请注意,现在成员的顺序发生了变化(b在c之前声明)。
我指的是内存访问“成本”或循环需要完成以读取/写入结构成员和/或任何其他相关的考虑因素?
是否依赖于编译器/体系结构(如果有的话)?
干杯,
盖。
答案 0 :(得分:4)
第一版和最后一版之间应该有很少或没有区别。在这两个结构中,int
成员在字边界上对齐,因此可以有效地从内存中读取它们。它们之间的唯一区别是填充位于c
中的b
和MyStructV1
之间,以及MyStructV2
中结构的末尾。但是由于填充没有执行开销;访问struct成员只需通过向结构开头的地址添加已知的偏移量即可完成。在MyStructV1
中b
的偏移量为8
,MyStructV2
4
{/ 1}}。{/ 1}
答案 1 :(得分:1)
如果char小于int(通常是这样),则结构MyStructV1可以小于MyStructV2。
取决于环境(体系结构和编译器选项),结构MyStructV1可以包围填充或可能未对齐b。 根据体系结构,如果b未对齐加载,则可能需要更多的cpu时钟。
此外,根据体系结构,读取一个可以加载更多东西立即可用,如果有填充,这个好处会减少或丢失。
答案 2 :(得分:0)
这更有趣,当然也有订购事宜。
struct aaa1{
char a;
char a1;
int b;
};
struct aaa2{
char a;
char a1;
char a2;
int b;
};
struct aaa3{
char a;
char a1;
char a2;
char a3;
int b;
};
struct aaa4{
char a1;
char a2;
char a3;
int b;
char a;
};
int main(void) {
struct aaa5{
char a;
int b;
char a1;
};
printf("%zu %zu %zu %zu %zu %zu\n", sizeof(struct aaa), sizeof(struct aaa1), sizeof(struct aaa2), sizeof(struct aaa3), sizeof(struct aaa4), sizeof(struct aaa5));
输出:8 8 8 8 12 12