代码之家  ›  专栏  ›  技术社区  ›  Raul Sofia

C结构内部的sempahores(sem_t)是否被填充以尊重对齐?

  •  2
  • Raul Sofia  · 技术社区  · 3 年前

    我目前正在C中定义一个结构(在Ubuntu x64中)。它看起来是这样的:

    #include <semaphore.h>
    #include <stdio.h>
    #include <stdbool.h>
    
    typedef struct key{
        sem_t sem;
        char name[32];
        int val1;
        int val2;
        char k;
        int n;
    } Key;
    
    

    据我所知(如果错误,请更正),x64中的结构成员将对齐8个字节,x32中的结构将对齐4个字节。这也是我选择32作为id数组大小的原因。

    我想知道的是:事实上(第一个成员是sem_t(显然是32个字节),下一个成员是那个或任何其他东西)第一个(sem)和第二个成员(在这种情况下是name)之间会有填充吗?或者它们是连续的?如果是,这对x32和x64都适用吗(因为32字节是4和8字节的倍数)?

    1 回复  |  直到 3 年前
        1
  •  2
  •   Jonathan Leffler    3 年前

    这取决于实施情况。你需要确定的一个问题是:你为什么担心?

    的大小 sem_t 可以在32位和64位实现之间变化。通常,当N是2的幂时,N字节对象(或N字节对象的数组)将在N字节边界上对齐。的对齐方式 double 并不总是遵循这个规则。如果你有 short (或 uint16_t )数据成员,它们只需要在2字节的边界上对齐 * 结构或活接头类型将根据具有最严格对准要求的构件的对准要求进行对准。

    之间不会有任何填充字节 sem 和 name 因为字符串可以在任何边界上对齐。之间可能有填充字节 名称 和 val1 ,但你可能避免了这一点(部分原因是你选择了32的长度 名称 )。

    您将在之间填充 k 和 n ;如果颠倒它们的顺序,则(可能)只有尾随填充,但由于只有一个字符,所以会有尾随填充。正如所写的,您有内部填充(可能有3个字节),可能没有尾部填充。

    要进一步调查,您需要使用 offsetof 宏来自 <stddef.h> ,但要注意,它只能报告当前实现,而不能报告其他实现。

    *从技术上讲 短的 不需要是16位或2个字节,但它几乎总是如此,我在这里假设也是如此。