通过C强制转换访问结构的第一个字段是否违反了严格的别名



此代码是否违反了严格的别名?

struct {int x;} a;
*(int*)&a = 3

更抽象地说,只要基元读/写操作的类型正确,在不同类型之间进行强制转换是否合法?

首先,在C中铸造是合法的。§6.7.2.1/13:

在结构对象中,非位字段成员和哪些位字段的地址按顺序增加它们被宣布。指向结构对象的指针,适当已转换,指向其初始成员(或者如果该成员是位字段,然后到它所在的单元),反之亦然。结构对象中可能有未命名的填充,但在其开始

混叠规则如下(§6.5/7):

对象的存储值只能由左值表达式访问,该左值表达式具有以下类型:

  • 与对象的有效类型兼容的类型
  • 与对象的有效类型兼容的类型的合格版本
  • 一个类型,它是与对象
  • 一个类型,它是与的限定版本相对应的有符号或无符号类型对象的有效类型
  • 一种聚合或并集类型,在其成员(递归地,包括子集合或包含联盟的成员),或
  • 字符类型

在这里,您将通过"与对象的有效类型兼容的类型"one_answers"在其成员中包括上述类型之一的聚合或联合类型"的指针来访问它,因此别名也没有问题。因此,在C中,通过将指向结构的指针投射到所讨论成员的类型来访问结构的第一个成员确实是完全合法的。

然而,在C++中,您经常会在C++对象的开头找到vtables和其他东西。然而,在您的特定情况下,您的结构是标准布局的,因此这是明确允许的(n3290中的§9.2/20,感谢Luc Danton!C++03显然有类似的规则,用POD对象表示)。

最新更新