C : typedef struct name {...}; VS typedef struct{...} name; -
as title says, have code :
typedef struct book{ int id; char title[256]; char summary[2048]; int numberofauthors; struct author *authors; }; typedef struct author{ char firstname[56]; char lastname[56]; }; typedef struct books{ struct book *arr; int numberofbooks; };
i these errors gcc :
bookstore.c:8:2: error: unknown type name ‘author’ bookstore.c:9:1: warning: useless storage class specifier in empty declaration [enabled default] bookstore.c:15:1: warning: useless storage class specifier in empty declaration [enabled default] bookstore.c:21:2: error: unknown type name ‘book’ bookstore.c:23:1: warning: useless storage class specifier in empty declaration [enabled default]
if change typedefs :
typedef struct{ char firstname[56]; char lastname[56]; } author;
then no warnings , no errors occur. having searched through http://www.amazon.com/c-programming-language-2nd-edition/dp/0131103628 , couple of hours googling can't figure why first implementation won't work.
there several things going on here. first, others have said, compiler's complaint unknown type may because need define types before using them. more important though understand syntax of 3 things: (1) struct definition, (2) struct declaration, , (3) typedef.
when defining struct, struct can named, or unnamed (if unnamed, must used (will explain means further below)).
struct name { ... };
this defines type called "struct name" can used declare struct variable:
struct name mynamestruct;
this declares variable called mynamestruct
struct of type struct name
.
you can define struct, , declare struct variable @ same time:
struct name { ... } mynamestruct;
as before, declares variable called mynamestruct
struct of type struct name
... but @ same time declares type struct name
.
type can used again declare variable:
struct name myothernamestruct;
now typedef way alias type specific name:
typedef oldtypename newtypename;
given above typedef, time use newtypename
same using oldtypename
. in c programming language particularly useful structs, because gives ability leave off word "struct" when declaring variables of type , treat struct's name type on own (as in c++). here example first defines struct, , typedefs struct:
struct name { ... }; typedef struct name name_t;
in above oldtypename struct name
, newtypename name_t
. now, declare variable of type struct name, instead of writing:
struct name mynamestruct;
i can simple write:
name_t mynamestruct;
note also, typedef can combined struct definition, , doing in code:
typedef struct { ... } name_t;
this can done while naming struct, superfluous:
typedef struct name { ... } name_t;
note well: in syntax above, since have started "typedef" whole statement typedef
statement, in oldtypename happens struct definition. therefore compiler interprets name coming after right curly brace } newtypename ... not variable name (as in syntax without typedef, in case defining struct , declaring struct variable @ same time).
furthermore, if state typedef, leave off name_t @ end, have created incomplete typedef statement, because compiler considers within "struct name { ... }
" oldtypename, , not providing newtypename typedef. why compiler not happy code have written (although compiler's messages rather cryptic because it's not quite sure did wrong).
now, noted above, if not name struct type @ time define it, must use either declare variable:
struct { ... } mynamestruct; // declares mynamestruct variable struct // definition, definition cannot re-used.
or can use unnamed struct type in typedef:
typedef struct { ... } name_t;
this final syntax did when wrote:
typedef struct{ char firstname[56]; char lastname[56]; } author;
and compiler happy. hth.
regarding comment/question _t suffix:
_t suffix convention, indicate people reading code symbolic name _t type name (as opposed variable name). compiler not parse, nor aware, of _t.
the c89, , particularly c99, standard libraries defined many types , chose use _t names of types. example c89 standard defines wchar_t, off_t, ptrdiff_t. c99 standard defines lot of types, such uintptr_t, intmax_t, int8_t, uint_least16_t, uint_fast32_t, etc. _t not reserved, nor specially parsed, nor noticed compiler, merely convention follow when defining new types (via typedef) in c. in c++ many people use convention start type names uppercase, example, mynewtype ( opposed c convention my_new_type_t ). hth
Comments
Post a Comment