问题描述
请考虑以下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.
推荐答案
严格别名规则是关于两种不同类型的引用相同的内存位置的。虽然你的例子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。一个指向结构对象,适当转换,道出了它的初始成员
以上两方面的考虑,使我想到你的code是合法的。
The two considerations above make me think that your code is legal.
这篇关于嵌套结构和在C严格别名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!