我不是初学者,我对以下习语非常熟悉:
typedef struct Foo_ Foo;// I know typedef struct Foo Foo is fine, I'm just trying to make it clearer
struct Foo_
{
int value;
Foo *link;
};
Run Code Online (Sandbox Code Playgroud)
我只是突然感到困惑,因为我的理解是在声明之前不允许使用名称(标识符).但在声明中typedef struct Foo_ Foo,标识符Foo_尚不存在!为什么编译器允许这种情况发生?请问有人对此有所了解,向我解释这种语法的理由是什么?
维基百科引用:目的typedef是为EXISTING类型指定替代名称.
---> 8 ---
感谢所有人提供了这么多有用的信息.
Jen*_*edt 30
这完全没问题.struct像你这样的标签的第一次使用是该struct类型的前向声明.
但是要注意你的使用_Foo是不符合.保留带有前导下划线和后跟大写字母的标识符.不要那样做.尾随下划线也没关系.
eca*_*mur 13
这在6.7.2.3p8中有所介绍:
6.7.2.3标签
语义
[...]8 - 如果形式为struct-or-union标识符的类型说明符不是作为[结构或联合定义]或[结构或联合声明]而发生的,并且标识符的其他标识声明不是可见,然后它声明一个不完整的结构或联合类型,并将标识符声明为该类型的标记.
类型说明符struct Foo在typedef struct Foo Foo不处于定义(struct Foo {...};)或声明(struct Foo;),所以它落在下6.7.2.3p8.
请注意,a没有什么特别之处typedef; 你也可以写
struct A { struct Foo *p; };
Run Code Online (Sandbox Code Playgroud)
并且不要求先前的定义或声明可见.
但是,在函数声明或定义中:
void foo(struct Foo *p);
Run Code Online (Sandbox Code Playgroud)
如果struct Foo先前未声明,那么声明的范围将只是函数声明或定义,并且它不会与任何后续声明或定义类型兼容Foo.