在声明之前键入一个struct

时间:2012-11-29 12:51:17

标签: 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;
};

我只是突然感到困惑,因为我的理解是在声明之前不允许使用名称(标识符)。但在声明typedef struct Foo_ Foo中,标识符Foo_尚不存在!为什么编译器允许这种情况发生?请问有人对此有所了解,向我解释这种语法的理由是什么?

维基百科引用:typedef的目的是为现有类型指定替代名称。

---> 8 ---

感谢所有人提供了这么多有用的信息。

7 个答案:

答案 0 :(得分:30)

这完全没问题。像您这样的struct标记的首次使用是struct类型的前向声明。

请注意,_Foo的使用符合要求。保留带有前导下划线和后跟大写字母的标识符。不要那样做。尾随下划线可以。

答案 1 :(得分:13)

这在6.7.2.3p8中有所介绍:

  

6.7.2.3标签

     的语义
     [...]      

8 - 如果形式 struct-or-union identifier 的类型说明符不是[struct-or-union definition]或[struct-or-union declaration],那么没有其他声明   标识符作为标记是可见的,然后它声明一个不完整的结构或联合类型,和   将标识符声明为该类型的标记。

struct Foo中的类型说明符typedef struct Foo Foo不在定义(struct Foo {...};)或声明(struct Foo;)中,因此它低于6.7.2.3p8。

请注意typedef没有什么特别之处;你也可以,例如写

struct A { struct Foo *p; };

并且不需要显示先前的定义或声明。

但是,在函数声明或定义中:

void foo(struct Foo *p);

如果先前未声明struct Foo,那么声明的范围将只是函数声明或定义,并且它不会与任何后续声明或定义类型兼容Foo

答案 2 :(得分:4)

ISO c99 : 6.2.1 Scopes of identifiers

7

结构,联合和枚举标记的范围在外观之后开始 声明标记的类型说明符中的标记。

typedef struct _Foo Foo; // You can do this because it's just the typedef the new type

struct _Foo *myfoo ; // It's pointer to struct _Foo (an incomplete type)
                      //but make sure before using myfoo->value   
                    // struct definition should be available

struct _Foo MyFoo;  // It's  definition of MyFoo but don't forget 
                    // to give the definition of struct _Foo (gcc extension). 

struct _Foo;  // forward declaration

struct _Foo    // It's the definition
{
    int value;
    Foo *link;
};

就像functions一样,我们在实际定义函数之前会forward declarationtypedef,所以我们也可以struct执行此操作。

void func(int );
typedef void (*func_t)(int);

void func(int x)
{
 //actual definition
}

答案 3 :(得分:3)

typedef用于为类型创建别名。但是当typedef'ed时,这种类型不一定存在。

例如,

如果您这样做:

struct Foo;

并且你永远不会在程序中的任何地方定义struct Foo,然后它仍然会编译。 编译器会认为它已在某处定义并继续。只有在不定义结构的情况下使用它,才会发生错误。

typedef也是类似的情况。

答案 4 :(得分:1)

在某些情况下,在声明之前使用struct ...类型是有效的。那就是所谓的“不完全类型”。

例如,将变量声明为指向“不完整”结构的指针以及(如您所见)typedef是有效的。

答案 5 :(得分:1)

它被称为向前声明。前向声明允许您在允许不完整类型的上下文中使用其名称。

编译器将“看到”typedef标记,并将其存储起来,直到找到类型为止,因此只要你在typedef之后声明了类型,但在任​​何使用之前,它就没问题了。

答案 6 :(得分:-1)

typedef声明允许您定义自己的标识符,这些标识符可用于代替int,float和double等类型说明符。 typedef声明不保留存储空间。

了解更多信息http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03typdef.htm