通过C强制转换访问结构的第一个字段是否违反了严格的别名
Does accessing the first field of a struct via a C cast violate strict aliasing?
此代码是否违反了严格的别名?
struct {int x;} a;
*(int*)&a = 3
更抽象地说,只要基元读/写操作的类型正确,在不同类型之间进行强制转换是否合法?
首先,在C中铸造是合法的。§6.7.2.1/13:
在结构对象中,非位字段成员和哪些位字段的地址按顺序增加它们被宣布。指向结构对象的指针,适当已转换,指向其初始成员(或者如果该成员是位字段,然后到它所在的单元),反之亦然。结构对象中可能有未命名的填充,但在其开始
混叠规则如下(§6.5/7):
对象的存储值只能由左值表达式访问,该左值表达式具有以下类型:
- 与对象的有效类型兼容的类型
- 与对象的有效类型兼容的类型的合格版本
- 一个类型,它是与对象
- 一个类型,它是与的限定版本相对应的有符号或无符号类型对象的有效类型
- 一种聚合或并集类型,在其成员(递归地,包括子集合或包含联盟的成员),或
- 字符类型
在这里,您将通过"与对象的有效类型兼容的类型"answers"在其成员中包括上述类型之一的聚合或联合类型"的指针来访问它,因此别名也没有问题。因此,在C中,通过将指向结构的指针投射到所讨论成员的类型来访问结构的第一个成员确实是完全合法的。
然而,在C++中,您经常会在C++对象的开头找到vtables和其他东西。然而,在您的特定情况下,您的结构是标准布局的,因此这是明确允许的(n3290中的§9.2/20,感谢Luc Danton!C++03显然有类似的规则,用POD对象表示)。
相关文章:
- std::shared_ptr 使用别名构造函数,是否可以检索初始指针值?
- 是否可以为 std::cout 创建别名?
- 严格的别名是否会阻止您通过其他类型写入 char 数组?
- 强制转换为不相关的引用类型是否违反严格的别名规则?
- 是否可以为模板类的模板函数成员设置别名?
- 使用容器中元素的别名删除带有 std::list::remove 的元素是否正确?
- 将空基类优化对象强制转换为另一种类型是否会破坏严格的别名?
- 别名漏洞是否适用于签名字符?
- 将结构别名为其第一个成员是否严格违反别名
- 是否可以将引用类型别名与指针运算符一起使用来声明对指针的引用?
- 如何检测模板是否为别名模板
- C++20 中的严格别名规则是否允许标准 c++ unicode 字符和下划线类型之间"reinterpret
- 严格别名规则是否适用于跨函数调用
- 链表的这个别名运算符是否会产生深度复制
- 如何检查函数中的模板参数是否与给定类型别名的专用化匹配
- c++11 严格别名规则是否允许通过 char *、char(&)[N],甚至 std::array<char、N> 和 -fstrict-aliasing -Wstrict-aliasi
- 命名空间别名是否会更改链接?
- 类型别名是否用作函数类型参数的一部分,是函数签名的一部分
- 已签名/未签名的别名规则是否按预期工作
- "size_t"是否始终是"vector<int>::size_type"或任何其他容器类型的别名?