嵌套结构和c中的严格别名

Joh*_*nes 17 c pointer-aliasing

请考虑以下代码:

typedef struct {
  int type;
} object_t;

typedef struct {
  object_t object;
  int age;
} person_t;

int age(object_t *object) {
  if (object->type == PERSON) {
    return ((person_t *)object)->age;
  } else {
    return 0;
  }
}
Run Code Online (Sandbox Code Playgroud)

这是合法代码还是违反了C99严格别名规则?请解释为何合法/非法.

das*_*ght 16

严格别名规则是指引用内存中相同位置的两个不同类型的指针(ISO/IEC9899/TC2).虽然您的示例将地址重新解释object_t object为地址person_t,但它不会object_t通过重新解释的指针引用内部位置,因为age它位于的边界之外object_t.由于通过指针引用的内存位置不相同,我会说它没有违反严格的别名规则.FWIW,gcc -fstrict-aliasing -Wstrict-aliasing=2 -O3 -std=c99似乎同意该评估,并没有产生警告.

但这还不足以确定它是合法代码:您的示例假设嵌套结构的地址与其外部结构的地址相同.顺便提一下,根据C99标准,这是一个安全的假设:

6.7.2.1-13.指向适当转换的结构对象的指针指向其初始成员

上面两个考虑使我认为您的代码是合法的.

  • @Johannes 我也喜欢这个问题,因为我有机会在回答这个问题的过程中学到一些新东西。具体来说,第二部分对我来说有点违反直觉:我不知道 C 禁止编译器在结构的初始成员之前填充。无论如何,如果您认为某个帖子回答了您的问题,那么接受答案是个好主意:您接受的 %% 会上升,并且您将在此过程中获得一枚徽章。祝你的 VM 项目好运! (2认同)