是否在C89中投射指向不同结构的指针?

mat*_*ots 13 c struct c89

我有两个结构

struct X {
  int x;
  double *y;
};

struct Y {
  int a;
  double *b;
  char c;
};
Run Code Online (Sandbox Code Playgroud)

是铸造的指针struct Y的指针struct X保证以合理的方式行为一致(即x->xx->y对应于y->ay->b由C89标准分别)?不太重要,但如果您也碰巧知道会非常酷,这对于后来的标准也是如此(例如C11)和其他与C语法重叠和语义重叠的语言(例如C++ XX,Objective-C) )?

use*_*ica 7

这是未定义的行为.Python之前依赖于此并且必须解决这个问题.如果您将struct Yinclude struct X作为其第一个元素,则可以使用它来获得类似的效果:

struct Y {
    struct X a;
    char c;
};

struct Y y;
struct X *x = (struct X *) &y; /* legal! */
Run Code Online (Sandbox Code Playgroud)

工会还有一个特例:

struct X {
  int x;
  double *y;
};

struct Y {
  int a;
  double *b;
  char c;
};

union XY {
    struct X x;
    struct Y y;
};

union XY xy;
xy.x.x = 0;
printf("%d\n", xy.y.a); /* legal! */
Run Code Online (Sandbox Code Playgroud)

在C标准的更高版本中,如果像这样的联合定义实际上在范围内,则编译器仅需要处理XY对象别名,但在C89中,它主要必须假设这样的定义存在于某处.尽管如此,这仍然不能安全地投射struct Y *到a struct X *; 如果编译器知道特定struct Y的不是联合的一部分,它仍然可能认为a struct X *不可能对它进行别名.