嵌套结构和在C严格别名 [英] Nested structs and strict aliasing in c

查看:177
本文介绍了嵌套结构和在C严格别名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下code:

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;
  }
}

这是法律code,或者它违反了C99严格别名规则?请解释为什么它是合法的/不合法的。

Is this legal code or is it violating the C99 strict aliasing rule? Please explain why it is legal/illegal.

推荐答案

严格别名规则是关于两种不同类型的引用相同的内存位置的(ISO / IEC9899 / TC2)。虽然你的例子reinter $ P $点的object_t对象的地址 PERSON_T 的地址,它不参考内存在 object_t 位置通过reinter preTED指针,因为年龄位于过去的边界 object_t 。由于通过指针引用的内存地址是不一样的,我会说,这不是违反了严格别名规则。 FWIW, GCC -fstrict走样-Wstrict走样= 2 -O3 -std = C99 似乎与考核同意,并且不产生警告。

Strict aliasing rule is about two pointers of different types referencing the same location in memory (ISO/IEC9899/TC2). Although your example reinterprets the address of object_t object as an address of person_t, it does not reference memory location inside object_t through the reinterpreted pointer, because age is located past the boundary of object_t. Since memory locations referenced through pointers are not the same, I'd say that it is not in violation of the strict aliasing rule. FWIW, gcc -fstrict-aliasing -Wstrict-aliasing=2 -O3 -std=c99 seems to agree with that assessment, and does not produce a warning.

这是不够的,决定了它是合法的code,虽然:你的榜样,使一个假设,即嵌套结构的地址是一样的,它的外部结构。顺便说一下,这是一个安全的假设根据C99标准做出

This is not enough to decide that it's legal code, though: your example makes an assumption that the address of a nested structure is the same as that of its outer structure. Incidentally, this is a safe assumption to make according to the C99 standard:

6.7.2.1-13。一个指向结构对象,适当转换,道出了它的初始成员

6.7.2.1-13. A pointer to a structure object, suitably converted, points to its initial member

以上两方面的考虑,使我想到你的code是合法的。

The two considerations above make me think that your code is legal.

这篇关于嵌套结构和在C严格别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆