- Typedef 必须描述一个实际的类型名称
- Typedef 后面需要
;
- 循环类型引用需要一些特殊的调味料
- 联合需要不同的成员名称
你的意思是:
struct ast_node; // forward declaration
typedef struct {
char* sym;
struct ast_node* value;
} ast_assignment;
typedef struct ast_conjunction {
char * sym;
struct ast_node* value;
} ast_conjunction;
typedef struct ast_node {
int node_type;
union {
ast_assignment data_asg;
ast_conjunction data_conj;
};
} ast_node;
稍微扩展一下以获得更完整的答案。
首先,typedef 的目的是将一个新名称安装到您可以使用的编译器中,因此typedef struct { ... }; 并没有真正做太多事情。它应该是typedef struct {...} newtype;,因此您可以使用实际名称newtype。
它后面还需要一个分号,每次我从 C# 回到 C 时都会把我搞砸 :-)
循环引用很棘手,提前使用struct mytype; 意味着您可以使用该名称mytype 只有在它是在不需要了解结构细节的情况下为人所知。在实践中,这意味着您可以使用 struct mytype * 作为指针 - 因为这是固定大小 - 但这是不允许的:
struct ast_node; // forward declaration
struct some_other_type {
struct ast_node *nodeptr; // this is ok
struct ast_node thisnode; // FAIL
...
};
原因是:无论指针指向什么类型的数据,指针都是固定大小的,所以编译器会带你一点,但thisnode 需要了解所有细节。抱歉,没办法。
Re:联合,你不能用两个同名成员定义任何union 或struct,因为你怎么能引用其中一个而编译器会知道哪个?
我个人不喜欢将typedef 用于结构类型,所以我会这样做:
struct ast_node; // forward struct defn
struct asg_assignment {
char *sym;
struct ast_node *value;
};
struct ast_conjunction {
char * sym;
struct ast_node* value;
};
struct ast_node {
int node_type;
union {
struct ast_assignment data_asg;
struct ast_conjunction data_conj;
};
};
...但我不确定我是否可以通过个人喜好以外的任何理由来证明这一点。