Need4Steed
Need4Steed

Reputation: 2180

typedef a struct before it's declared

I'm not a beginner, I'm very familiar with the following idiom:

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;
};

I'm just suddenly feel confused, because my understanding is that it's not allowed to use a name(identifier) before it's declared. But in the declaration typedef struct Foo_ Foo, the identifier Foo_ does not yet exist! How come the compiler permit this happen? Would anybody please shed some light on this, explain to me what's the justification for this kind of syntax?

Wikipedia quote : The purpose of typedef is to assign alternative names to EXISTING types.

--- >8 ---

Thank you all guys for so much helpful information.

Upvotes: 34

Views: 12836

Answers (7)

Omkant
Omkant

Reputation: 9204

ISO c99 : 6.2.1 Scopes of identifiers

7

Structure, union, and enumeration tags have scope that begins just after the appearance of the tag in a type specifier that declares the tag.

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;
};

Simply as for functions we do forward declaration or typedef before actual definition of function , So we can do it with struct also.

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

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

Upvotes: 4

ecatmur
ecatmur

Reputation: 157354

This is covered in 6.7.2.3p8:

6.7.2.3 Tags

Semantics
[...]

8 - If a type specifier of the form struct-or-union identifier occurs other than as [a struct-or-union definition] or [a struct-or-union declaration], and no other declaration of the identifier as a tag is visible, then it declares an incomplete structure or union type, and declares the identifier as the tag of that type.

The type specifier struct Foo in typedef struct Foo Foo is not in a definition (struct Foo {...};) or a declaration (struct Foo;) so it falls under 6.7.2.3p8.

Note that there's nothing special about a typedef; you could also e.g. write

struct A { struct Foo *p; };

and a previous definition or declaration is not required to be visible.

However, in a function declaration or definition:

void foo(struct Foo *p);

if struct Foo is not previously declared then the scope of the declaration will just be the function declaration or definition, and it will not be type-compatible with any subsequent declaration or definition of Foo.

Upvotes: 15

P.P
P.P

Reputation: 121387

typedef is used to create an alias for a type. But that type doesn't necessarily exist when typedef'ed.

For example,

if you just do:

struct Foo;

and you never define the struct Foo anywhere in the program, then it'll still compile. Compiler would assume it's defined somewhere and continue. Only if you use it without defining the struct, an error will occur.

It's the similar case with typedef as well.

Upvotes: 3

Mike
Mike

Reputation: 49403

It's called forward declaring. The forward declaration allows you to use its name in context where an incomplete type is allowed.

The compiler will "see" the typedef tag, and store it away until the type is found, so as long as you have the type declared in there after the typedef, but before any usage, it's fine.

Upvotes: 2

glglgl
glglgl

Reputation: 91029

Under certain circumstances, it is valid to use a struct ... type before it is declared. It is a so-called "incomplete type" then.

For example, it is valid to declare a variable as a pointer to an "incomplete" struct, as well as (as you can see) a typedef.

Upvotes: 1

Jens Gustedt
Jens Gustedt

Reputation: 78903

This is completely fine. The first use of struct tag like yours is a forward declaration of the struct type.

Beware though that your usage of _Foo is not conforming. Identifiers with leading underscore and following capital letter are reserved. Don't do that. Trailing underscore would be ok.

Upvotes: 34

akp
akp

Reputation: 1823

A typedef declaration lets you define your own identifiers that can be used in place of type specifiers such as int, float, and double. A typedef declaration does not reserve storage.

for more info http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=%2Fcom.ibm.vacpp6m.doc%2Flanguage%2Fref%2Fclrc03typdef.htm

Upvotes: -2

Related Questions