我知道int* ptr = (int*)buffer
(其中buffer
是char*
)会中断
严格别名规则。
这种语法int& ref = (int&)(*buffer)
是否也违反了规则?
答案 0 :(得分:3)
这不行(假设您将使用所述引用来访问该值)。 §3.10[basic.lval]¶10C ++ 14标准(引用N4140)说(强调我的):
如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:
- 对象的动态类型,
- 对象的动态类型的cv限定版本,
- 与对象的动态类型相似的类型(如4.4中所定义)
- 与对象的动态类型对应的有符号或无符号类型的类型
- 对应于动态类型的cv限定版本的有符号或无符号类型 对象,
- 聚合或联合类型,包括其元素或非静态数据成员中的上述类型之一(递归地,包括子聚合的元素或非静态数据成员) 或包含联盟),
- 一种类型,它是对象动态类型的(可能是cv限定的)基类类型,
char
或unsigned char
类型。
您是否尝试通过指针或引用进行访问无关紧要。对于char
类型的存储对象,没有一个项目符号适用于允许它作为int
访问它。
最后一个要点仅表示您可以将任何其他类型别名为char
,但反之亦然。这是有道理的,因为char
是具有最弱对齐要求的最小可寻址单元。
如果需要,使用指针与使用引用相同,除非您需要显式取消引用才能访问该值。
答案 1 :(得分:2)
严格的别名规则意味着你不应该取消引用指向同一内存位置的不同类型的指针。
由于在您发布的代码中您永远不会取消引用,因此无法在不查看所有代码的情况下判断是否违反规则。
此外,别名为char *类型是一个例外,并且不违反规则。这意味着您可以通过将其指针转换为char *并取消引用来访问包含任何类型的内存位置。
总结:
buffer
指向包含int的内存位置,并且已从int*
转换为char*
,则此选项有效。但是,您应该使用reinterpret_cast
作为此int* ptr
会违反规则。答案 2 :(得分:2)
是的,确实如此。
C和C ++特殊情况都不能通过指针与其他访问进行访问,无论您使用指针,引用还是任何其他左值,严格的别名规则都适用。
如果遇到麻烦,最简单的解决方案是使用memcpy将内存位置复制到局部变量中 - 任何自尊的编译器都会完全优化这个memcpy,只将其视为别名提示(memcpy也是首选)在工会上,因为工会方法不那么便携。)