代码之家  ›  专栏  ›  技术社区  ›  0.sh

在检查联合成员[重复]的字节偏移量数目时,offsetof返回0。

c
  •  0
  • 0.sh  · 技术社区  · 7 年前

    这个问题已经有了答案:

    如标题所示,我希望从该成员之前的其他成员(使用 offsetof 宏定义于 stddef.h )这对结构起到了预期的作用

    #include <stdio.h>
    #include <stddef.h>
    
    struct bio {
      int age;
      char name;
    };
    
    
    int main( void ) {
      printf("%d\n", offsetof(struct bio, name));  // result is 4 , which is what i expected
    }
    

    但对于工会,它打印了0

    #include <stdio.h>
    #include <stddef.h>
    
    union bio {
      int age;
      char name;
    };
    
    
    int main( void ) {
      printf("%d\n", offsetof(union bio, name)); // 0
    }
    

    只是一个后续问题,这种行为的原因是因为联合的成员存储在同一个内存块中吗?

    作为解释 wikipedia offsetof 我还期望得到4的值,而不是0的值

    2 回复  |  直到 7 年前
        1
  •  3
  •   Koldar    7 年前

    在联合中,分配的空间是联合中每个字段所需的最大字节数。对于Bio(假设 sizeof(int)=4 ):

    sizeof(bio) = max(sizeof(int), sizeof(char)) = sizeof(4, 1) = 4
    

    这是因为所有联合字段共享相同的内存空间,从联合本身开始。

    bio.age = 24
    bio.name = 'a' //a will use the first byte in the union, just like the first byte of the integer
    

    你也可以通过打印指针来检查它。

        2
  •  3
  •   Stephan Lechner    7 年前

    根据定义,联合描述了一组重叠的非空成员对象,以便成员共享相同的内存位置。这意味着每个成员的地址是相同的。此外,根据定义,此类成员的地址与联合对象本身的地址相同,因此每个成员的偏移量必须为 0 (例如,CF this 在线C标准草案;重点是我的):

    6.7.2.1结构和联合规范

    16.)工会的规模足以容纳其最大成员。最多可以将一个成员的值存储在 随时合并对象。 指向联合对象的指针,适当地 转换后,指向它的每个成员(或者如果成员是位- 字段,然后是它所在的单元),反之亦然。