20

将一种类型转换为另一种类型是 C 语言中的一种常见策略,这依赖于 C 结构的布局具有一定保证的事实。诸如 GLib 之类的库依靠它来实现类似继承的面向对象。基本上:

struct Base
{
  int x;
  int y;
};

struct Derived
{
  struct Base b;
  int z;
};

这使得一个Base*指针能够分配给Derived对象的地址。

但我也知道“严格的别名”规则,这是编译器隐含的假设,即不同类型的指针不能指向同一个地址。(这使编译器能够执行某些优化。)

那么,这两件事是如何调和的呢?许多 C 库,包括 Glib、CPython 等,都使用上述策略在类型之间进行强制转换。他们都是简单地用像这样的标志编译no-strict-aliasing吗?

4

1 回答 1

21

在这种情况下,没有违反严格别名。 struct Derived 包含一个struct Base. 语言标准明确允许这种行为。从 C11 6.7.2.1 结构和联合说明符,第 15 段:

一个指向结构对象的指针,经过适当的转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。

于 2013-09-25T17:03:54.037 回答