通过引用访问是否违反了严格的别名规则?

Does access by reference violate strict aliasing rule?

我知道 int* ptr = (int*)buffer(其中 bufferchar*)中断 严格别名规则。

这个语法int& ref = (int&)(*buffer)是否也违反了规则?

一些 SEGFAULT 由于违反了严格的别名规则,而这个语法已经消除了它。虽然可能仍然不正确,是吗?

严格的别名规则意味着您不应解引用指向同一内存位置的不同类型的指针。

由于在您发布的代码中您从不取消引用,因此在不查看所有代码的情况下无法判断这是否违反了规则。

此外,为 char* 类型起别名是一个例外,并不违反规则。这意味着您可以通过将其指针转换为 char* 并取消引用来访问包含任何类型的内存位置。

总结:

  • 如果 buffer 指向一个包含 int 的内存位置,并且从 int* 转换为 char*,这是有效的。但是,您应该为此使用 reinterpret_cast
  • 如果缓冲区指向包含字符的内存位置,取消引用 int* ptr 确实违反了规则。
  • 参考版本很可能遇到同样的问题。但是编译器没有义务阻止或警告你这样做
  • 不要使用 C 风格转换,而是使用 reinterpret_cast,并阅读关于哪些用户定义了行为的标准。

这不行(假设您要使用所述引用来访问该值)。 § 3.10 [basic.lval] ¶ C++14 标准的第 10 条(引用 N4140)说(强调我的):

If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined:

  • the dynamic type of the object,
  • a cv-qualified version of the dynamic type of the object,
  • a type similar (as defined in 4.4) to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,
  • a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its elements or non-static data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
  • a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
  • a char or unsigned char type.

无论您尝试通过指针还是引用进行访问都没有关系。对于 char 类型的存储对象,none 的要点适用于允许将其作为 int.

访问

最后一个要点仅表示您可以将任何 other 类型作为 char 的别名,但反之则不行。这是有道理的,因为 char 是具有最弱对齐要求的最小可寻址单元。

如果需要,使用指针与使用引用相同,只是您需要明确取消引用才能访问值。

是的,确实如此。

无论是 C 还是 C++ 特殊情况下都不是通过指针访问与其他访问,无论您是使用指针、引用还是任何其他左值,都适用严格的别名规则。

如果您 运行 遇到麻烦,最简单的解决方案是使用 memcpy 将内存位置复制到局部变量中 - 任何自尊的编译器都会完全优化这个 memcpy 并仅将其视为别名提示(memcpy 也优于联合,因为联合方法不那么可移植)。