为什么结构中没有填充只用于" char"类型成员?

时间:2017-11-16 07:37:14

标签: c gcc char structure padding

我在结构中只声明了char个类型的成员。

#include <stdio.h>

struct st
{
    char c1;
    char c2;
    char c3;
    char c4;
    char c5;
};

int main() {
    struct st s;
    printf("%zu\n", sizeof(s));
    return 0;
}

输出 [Live Demo]

5

那么,为什么结构中只有char类型成员没有填充?

3 个答案:

答案 0 :(得分:7)

Padding是强制执行 alignment requeriments。如果成员位于可被其大小整除的地址,则称该成员对齐(其大小)。

您的示例中不需要填充,因为st结构的所有成员已经与其大小对齐,即:st的每个成员的地址已经可以被其大小整除。所有成员的类型为charchar的大小为 1 。如果成员的大小为 1 ,则该成员始终与其大小对齐,因为任何地址都可以被 1 整除。

答案 1 :(得分:5)

结构中的填充存在(主要是),以强制个别成员与其基本对齐要求对齐,即({{ 3}}):

  

要求特定类型的对象位于存储边界上,其地址是字节地址的特定倍数

结构中间和末端的填充用于确保即使在这些结构的数组中,每个成员仍将根据其对齐要求对齐。 C11 3.2p1

  

完整对象类型具有对齐要求,这些要求对可以分配该类型的对象的地址施加限制。对齐是实现定义的整数值,表示可以分配给定对象的连续地址之间的字节数。对象类型对该类型的每个对象强制对齐要求:可以使用_Alignas关键字请求更严格的对齐。

现在,每个其他类型的对齐要求都是实现定义的,但有一点是隐含的:因为对齐要求用size_t表示; sizeof (char)为1,并且指向字符类型的指针可用于处理其他类型的每个单独字符,字符类型不能具有大于1的基本对齐要求。令人惊讶的是,这在C标准中并未详细说明。所有;它只是这个模糊的措辞(C11 6.2.8p1):

  

类型charsigned charunsigned char应具有最弱的对齐要求。

由于char的对齐最多为1,编译器不需要添加任何填充,因为即使结构正好是5个字节长,那么即使在数组中也是如此一些结构从奇数地址开始,这些结构的每个成员仍然可以正确对齐。

答案 2 :(得分:0)

某些类型,如果正确对齐,则具有更好的性能/稳定性等。当这种类型的变量后面有其他变量使其起始位置“未对齐”时,编译器可能决定添加填充,以便对齐进展顺利。这都是可选的,当然你没有必要的是字节(char)。

如果您编写这样的结构,您将更有可能观察填充:

struct pad{
    int8_t a;
    int64_t b;
};
assert(sizeof(struct pad) == 16);

其内存布局应如下所示:

|---|-------|---------|
| 1 |   7   |    8    |
|---|-------|---------|
byte|padding|64-bit int

然后再次,不需要对齐字节,因为它们是最小的存储单元。