别名和有效类型
违反别名规则和违反对象的有效类型是两回事,不应混淆。
-
别名是两个指针
a
和b
的属性,它们指的是同一个对象,即a == b
。 -
C 使用数据对象的有效类型来确定可以对该对象执行哪些操作。特别地,有效类型用于确定两个指针是否可以彼此别名。
别名可能是优化的问题,因为通过一个指针改变对象,a
说,可以改变通过另一个指针 b
可见的对象。如果你的 C 编译器必须假设指针总是可以互为别名,无论它们的类型和来源如何,许多优化机会都会丢失,并且许多程序运行速度会变慢。
C 的严格别名规则是指编译器中的情况可以假设哪些对象相互做(或不相互)别名。对于数据指针,你应始终牢记两条经验法则。
除非另有说明,否则具有相同基类型的两个指针可能是别名。
具有不同基类型的两个指针不能别名,除非这两种类型中的至少一种是字符类型。
这里基类型意味着我们放弃了 const
等类型资格,例如,如果 a
是 double*
而 b
是 const double*
,编译器通常必须假设*a
的更改可能会改变*b
。
违反第二条规则可能会产生灾难性后果。这里违反严格的别名规则意味着你向编译器提供两个不同类型的指针 a
和 b
,它实际上指向同一个对象。然后,编译器可能总是假设两者指向不同的对象,并且如果你通过*a
更改了对象,则不会更新其对*b
的想法。
如果这样做,程序的行为将变得不确定。因此,C 对指针转换施加了相当严格的限制,以帮助你避免意外发生这种情况。
除非源或目标类型是
void
,否则具有不同基类型的指针之间的所有指针转换必须是显式的。
或者换句话说,他们需要一个演员阵容,除非你进行转换只是将一个限定符如 const
添加到目标类型。
一般来说,避免指针转换和特别是强制转换会保护你免受别名问题的影响。除非你真的需要它们,并且这些情况非常特殊,你应该尽可能地避免它们。