3

这可能是我做错了什么非常愚蠢的事情,但我无法弄清楚它是什么。

我有一个 struct PDRect,其成员是 aPDPointPDSize

typedef struct {
    GLfloat x, y;
} PDPoint;

typedef struct {
    GLfloat width, height;
} PDSize;

typedef struct {
    PDPoint origin;
    PDSize size;
} PDRect;

当我实例化一个时,像这样:

PDRect rect = {
    .origin = {
        .x = 0,
        .y = 0
    },
    .size = {
        .height = .5,
        .width = .5
    }
};

调试器说rect.origin.widthandrect.origin.height都存在且等于 0,rect.size.xandrect.size.y都存在且等于 0.5。我不知道为什么会这样。

为清晰而编辑:我的困惑是为什么 rect.origin(它是一个 PDPoint)具有与之关联的高度和宽度值,而 rect.size(它是一个 PDSize)具有与之关联的 x 和 y 值。原点不应该只有 x 和 y 并且大小只有高度和宽度吗?

编辑:它实际上修复了它让它们以非匿名方式声明,即:

typedef struct _PDPoint {
    GLfloat x, y;
} PDPoint;

typedef struct _PDSize {
    GLfloat width, height;
} PDSize;

typedef struct _PDRect {
    PDPoint origin;
    PDSize size;
} PDRect;

我仍然不确定我是否真的理解为什么会有所作为,但它似乎已经解决了这个问题。

4

1 回答 1

1

我认为问题的发生是因为您同时使用匿名结构和类型定义。当 C 编译器看到

struct {...} name;

构造它实际上改变的是它

struct anonymous {...} name;

现在这就是我认为正在发生的事情:......我说我认为因为我无法重现你的例子。我只是将类型更改为浮点数并在 FreeBSD amd64/gcc 版本 4.2.1 20070831 上运行它。代码如下。

#include <stdio.h>

typedef struct {
  float x, y;
} PDPoint;

typedef struct {
  float width, height;
} PDSize;

typedef struct {
  PDPoint origin;
  PDSize size;
} PDRect;

int main(int argc, char *argv[]) {
  PDRect rect = {
    .origin = {
      .x = 1,
      .y = 1
    },
    .size = {
      .height = .5,
      .width = .5
    }
  };
  printf("w:%f h:%f x:%f y:%f\n",rect.size.width,rect.size.height,
      rect.origin.x,rect.origin.y);
  return 0;
}

输出

w:0.500000 h:0.500000 x:1.000000 y:1.000000

应该...如果您可以尝试以下内容,那将很有趣。更改其中一个结构以保存整数并查看交换是否再次发生。还尝试将 2 个字段初始化为非零值,以检查您是否导致它或其默认分配值。
我认为正在发生的是,编译器使用您的代码按以下顺序执行操作:

a)它看到一个名为 anonymous 的结构,它接受 2 个浮点数,将其存储在堆栈中并将其命名为 PDPoint

b)它看到一个名为 anonymous 的结构,它接受 2 个浮点数,将其存储在堆栈中并将其命名为 PDSize

c)在查找 PDPoint 以定义它从堆栈中弹出()的第三个结构时,名为匿名的结构需要 2 个浮点数。但此时这会解析为 PDSize。

d)对于 PDSize,只有 PDPoint 留在堆栈上,实际上它是一个名为匿名的结构,需要 2 个浮点数。;)

typedef 和声明结构的正确方法是

typedef struct name_t { ... } name;

尽管有些人会争辩说,现在你可以放弃 _t 约定(它是为 POSIX 保留的)。tl; dr:小心匿名结构。

于 2012-12-09T01:35:42.677 回答