c++ - 严格别名是 C 还是 C++ 的东西?

标签 c++ c casting strict-aliasing

在 ISO/IEC 9899:TC2 中,标准说明如下

6.3.2.3 Pointers

  1. A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object. Successive increments of the result, up to the size of the object, yield pointers to the remaining bytes of the object.

因此,标准中并不清楚一种类型的指针是否可以转换为另一种类型的指针。

最佳答案

其他地方定义了严格的别名规则。这是措辞:

C(ISO/IEC 9899:1999 6.5/7):

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

  • a type compatible with the effective type of the object,
  • a qualified version of a type compatible with the effective type of the object,
  • a type that is the signed or unsigned type corresponding to the effective type of the object,
  • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
  • a character type.

C++(ISO/IEC 14882:2011 3.10 [basicl.lval]/15):

If a program attempts to access the stored value of an object through an lvalue 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.

C 标准不禁止您将指针转换为不相关的类型,前提是没有对齐问题。但是,由于严格的别名规则,您基本上不能取消引用从此类转换中获得的指针。因此,处理这种“无效”指针的唯一有用的方法是将其转换回正确的类型(或兼容类型)。

它在 C++ 中与 reinterpret_cast (5.2.10 [expr.reinterpret.cast]/7) 基本相同:

An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast<cv T2*>(static_cast<cv void*>(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.

关于c++ - 严格别名是 C 还是 C++ 的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7291874/

相关文章:

php - PHP MYSQL 组合的转换问题

c# - 来自基类的用户定义转换运算符

android - 不明白 Android 中的 java.lang.ClassCastException 错误

c - 使用地理坐标查找指南针方向

c - 查找 C 语言中最长的单词

android - 如何设置eclipse在构建过程中不删除某些文件

c++ - Guid.NewGuid() 的 C++ 版本是什么?

c++ - 为什么不总是使用 fpic(位置无关代码)?

c++ - OOP 中的 GLFWwindowsizefun 可访问性

c++ - 在 x + y 中获取 "carry"