在声明之前键入一个struct

Nee*_*eed 30 c typedef

我不是初学者,我对以下习语非常熟悉:

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符合.保留带有前导下划线和后跟大写字母的标识符.不要那样做.尾随下划线也没关系.

  • 这是否意味着`typedef struct Foo_ Foo`实际上是`struct Foo_; typedef struct Foo_ Foo;`合并在一起? (7认同)
  • @ Need4Steed,是的,确切地说,这是一个很好的方式. (2认同)
  • 我明白了,它确实是有道理的,因为我们可以像typedef struct Foo Foo;那样写成`typedef struct Foo {...} Foo;`之类的东西,只省去{{...}`部分。 (2认同)

eca*_*mur 13

这在6.7.2.3p8中有所介绍:

6.7.2.3标签

语义
[...]

8 - 如果形式为struct-or-union标识符的类型说明不是作为[结构或联合定义]或[结构或联合声明]而发生的,并且标识符的其他标识声明不是可见,然后它声明一个不完整的结构或联合类型,并将标识符声明为该类型的标记.

类型说明符struct Footypedef 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.