C:铸造具有不同尺寸
问题描述:
快速简单的问题结构; 这是否C:铸造具有不同尺寸
typedef struct {int a; int b;} S1;
typedef struct {int a;} S2;
((S2*)(POINTER_TO_AN_S1))->a=1;
总是返回(和分配)的部件结构的?或者它是不确定的行为?
答
在相符的编译器,如果两个结构类型出现的联合类型,其是可见的,其中所述结构被访问,并且如果指针的目标正好是该联合类型的一个实例,行为会的完整的定义内被定义。请注意,标准并不要求编译器有任何方式知道指针的目标实际上是该联合类型的一个对象 - 仅仅是整个联合类型的声明是可见的。
注意,但是,GCC不被这里的标准遵守,除非使用-fno-strict-aliasing
标志。即使在整体联合类型可见的情况下,编译器可以看到它实际上处理联合类型的对象,gcc也会忽略别名。例如,给定:
struct s1 {int x;};
struct s2 {int x;};
union u { struct s1 s1; struct s2 s2;};
int read_s1_x(struct s1 *p) { return p->x; }
int read_s2_x(struct s2 *p) { return p->x; }
int write_s1_x(struct s1 *p, int value) { p->x = value; }
int write_s2_x(struct s2 *p, int value) { p->x = value; }
int test(union u *u1, union u *u2)
{
write_s2_x(&u2->s2, 0);
if (!read_s1_x(&u1->s1))
write_s2_x(&u2->s2, 1);
return read_s1_x(&u1->s1);
}
编译器将决定它没有也不需要重新读取的 U1-> s1.x写入后U2-> s2.x,即使价值完成联合类型 是可见的,即使编译器可以看到,无论是U1和U2是 指向工会类型的对象。我不太知道什么GCC的 笔者认为地址的运营商应该在 应用于联合类型,如果结果指针甚至不能被用来 立即访问该成员类型的对象来表示。当代码中包含(即几乎都是在这里对堆栈溢出)
语言标记是很重要的。 – crashmstr