By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,412 Members | 993 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,412 IT Pros & Developers. It's quick & easy.

question about struct??

P: n/a
Hi, all. I feel confuse about below struct definition:
typedef struct TAG
{
comments....
};
What my confusion is: is typedef extra??why we not just use
struct TAG
{
comments....
};
My question is: is there any difference between them?
Thanks

Feb 15 '06 #1
Share this Question
Share on Google+
20 Replies


P: n/a
hi...

in plain C, when you 'typedef' something, it then behaves as a builtin
type.
So, if you exclude the 'typedef' keyword from your example above, you
would have to type

void function(struct TAG * tagptr);

with typedef, you can just write

void function(TAG * tagptr);

bye :)

Feb 15 '06 #2

P: n/a
Hi

typedef is like alias command in Linux. You can alias(define) a type of
yourself.

If you use typedef struct TAG{ }Tag;
then you can do :
Tag mystruct;
to declear a struct;

If you use struct TAG{ }Tag;
then you must do:
struct Tag mystruct;
to declear a struct;

It is the only difference I see;

See http://www.c-faq.com/struct/typedef.html

ma******@ntu.edu.sg wrote:
Hi, all. I feel confuse about below struct definition:
typedef struct TAG
{
comments....
};
What my confusion is: is typedef extra??why we not just use
struct TAG
{
comments....
};
My question is: is there any difference between them?
Thanks


Feb 15 '06 #3

P: n/a
ok. But my point is that:
what is difference about typedef struct TAG { };and struct TAG { };
(pls take note that there is no variable behind struc definition! ).
Thanks

Feb 15 '06 #4

P: n/a
ma******@ntu.edu.sg writes:
Hi, all. I feel confuse about below struct definition:
typedef struct TAG
{
comments....
};
What my confusion is: is typedef extra??why we not just use
struct TAG
{
comments....
};
My question is: is there any difference between them?


You messed up the typedef. There are actually (at least) three
variants of what you're asking about.

1:
typedef struct foo {
/* member declarations */
} foo_t;

2:
typedef struct {
/* member declarations */
} foo_t;

3:
struct foo {
/* member declarations */
};

In these examples, "foo" is a struct tag, and "foo_t" is a typedef
(which is simply an alias for an existing type).

In example 1, we have two names for the same type, "struct foo" and
"foo_t". Note that struct tags are in their own namespace, so there's
no real need to use two different identifiers; you could have
typedef struct foo {
/* member declarations */
} foo;
Again, this gives you two names for the same thing, "struct foo" and
"foo".

In example 2, we declare an anonymous struct (with no tag) and then
create the name "foo_t" as an alias for it.

In example 3, there's no typedef, so we can only refer to the type as
"struct foo".

The form in example 1 is fairly common, but personally I prefer
example 3. There's really not much advantage in having an additional
alias for something that already has a perfectly good name. And you
need the "struct foo" form anyway if the structure needs to have a
member that's a pointer to the same type (e.g., for a linked list
node).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 15 '06 #5

P: n/a
Thank you very much! :p

Feb 15 '06 #6

P: n/a
ma******@ntu.edu.sg writes:
Thank you very much! :p


You're welcome. And *please* read <http://cfaj.freeshell.org/google/>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 15 '06 #7

P: n/a
<Ro*****@gmail.com> wrote in message
news:11**********************@g44g2000cwa.googlegr oups.com...
Hi

typedef is like alias command in Linux. You can alias(define) a type of
yourself.

If you use typedef struct TAG{ }Tag;
then you can do :
Tag mystruct;
to declear a struct;

If you use struct TAG{ }Tag;
then you must do:
struct Tag mystruct;
struct TAG mystruct;
Tag is an instance of a struct TAG.
to declear a struct;

Feb 15 '06 #8

P: n/a

"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...
You messed up the typedef. There are actually (at least) three
variants of what you're asking about.

1:
typedef struct foo {
/* member declarations */
} foo_t;

2:
typedef struct {
/* member declarations */
} foo_t;

3:
struct foo {
/* member declarations */
};

In these examples, "foo" is a struct tag, and "foo_t" is a typedef
(which is simply an alias for an existing type).

In example 1, we have two names for the same type, "struct foo" and
"foo_t". Note that struct tags are in their own namespace, so there's
no real need to use two different identifiers; you could have
typedef struct foo {
/* member declarations */
} foo;
Again, this gives you two names for the same thing, "struct foo" and
"foo".

In example 2, we declare an anonymous struct (with no tag) and then
create the name "foo_t" as an alias for it.

In example 3, there's no typedef, so we can only refer to the type as
"struct foo".

The form in example 1 is fairly common, but personally I prefer
example 3. There's really not much advantage in having an additional
alias for something that already has a perfectly good name. And you
need the "struct foo" form anyway if the structure needs to have a
member that's a pointer to the same type (e.g., for a linked list
node).


You could do it this way, which i find elegant:

typedef struct foo *foo_ptr;
struct foo {
/*other member declarations*/
foo_ptr next;
};
Feb 15 '06 #9

P: n/a
fr*******@gmail.com wrote:

in plain C, when you 'typedef' something, it then behaves as a builtin
type.


Please read the information below.

Brian

--
Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.
Feb 15 '06 #10

P: n/a
Ro*****@gmail.com wrote:
Hi ma******@ntu.edu.sg wrote:
Hi, all. I feel confuse about below struct definition:

Please don't top-post, your comments should follow or (preferably) be
interspersed with properly trimmed quotes.

Brian
Feb 15 '06 #11

P: n/a
"stathis gotsis" <st***********@hotmail.com> writes:
"Keith Thompson" <ks***@mib.org> wrote in message
news:ln************@nuthaus.mib.org...

[snip]
The form in example 1 is fairly common, but personally I prefer
example 3. There's really not much advantage in having an additional
alias for something that already has a perfectly good name. And you
need the "struct foo" form anyway if the structure needs to have a
member that's a pointer to the same type (e.g., for a linked list
node).


You could do it this way, which i find elegant:

typedef struct foo *foo_ptr;
struct foo {
/*other member declarations*/
foo_ptr next;
};


Hiding a pointer type behind a typedef is potentially even more
confusing than hiding a struct behind a typedef. I would write the
above as:

struct foo {
/* other member declarations */
struct foo *next;
};

Much simpler and less error-prone.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 15 '06 #12

P: n/a
Rob
ma******@ntu.edu.sg wrote:
Hi, all. I feel confuse about below struct definition:
typedef struct TAG
{
comments....
};
What my confusion is: is typedef extra??why we not just use
struct TAG
{
comments....
};


I think it needs to be emphasised how a typedef tells the compiler that
it is a new type, and is more than merely a #define.

/* Code 1:
typedef struct {int a; int b;} st;

void some_func(st s) {

return;
}

int main() {
st v;

some_func(v);
}
*/
/* Code 2:
void some_func(struct {int a; int b;} s) {

return;
}

int main() {
struct {int a; int b;} v;

some_func(v);
}
*/
/* Code 3:
#define st struct {int a; int b;}

void some_func(st s) {

return;
}

int main() {
st v;

some_func(v);
}
*/
Code 1 works fine. Code 2 is the same as code 1, but with every
instance of "st" replaced with the actual definition. It won't
compile. Code 3 is the same but uses a #define; as can be expected it
also does not work.

Feb 16 '06 #13

P: n/a
"Rob" <io*********@hotmail.com> writes:
ma******@ntu.edu.sg wrote:
Hi, all. I feel confuse about below struct definition:
typedef struct TAG
{
comments....
};
What my confusion is: is typedef extra??why we not just use
struct TAG
{
comments....
};


I think it needs to be emphasised how a typedef tells the compiler that
it is a new type, and is more than merely a #define.


No, a typedef does not create a new type; it merely creates an alias
for an existing type. You can write perfectly good code without using
typedef at all. For example:

struct st {
int a ;
int b;
};

You can then refer to the type simply as "struct st". A typedef
merely creates a second name for the same type.

See also <http://www.c-faq.com/struct/typedef.html>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 16 '06 #14

P: n/a
Rob
Keith Thompson wrote:
I think it needs to be emphasised how a typedef tells the compiler that
it is a new type, and is more than merely a #define.


No, a typedef does not create a new type; it merely creates an alias
for an existing type. You can write perfectly good code without using
typedef at all. For example:

struct st {
int a ;
int b;
};

You can then refer to the type simply as "struct st". A typedef
merely creates a second name for the same type.


My point was that typedef tells the compiler to regard it as a type,
e.g. that:
#define i int
and:
typedef int i
are effectively, but not functionally, equivalent.

I used to think that a struct definition could be used interchangeably
with a type keyword:

struct {int a; int b;} var;

But then I found out that this premise is wrong and the above code
useless, since everywhere you explicitly place a struct definition, it
defines a new struct, i.e.:

struct {int a; int b;} var;
struct {int a; int b;} _var;

_var and var are treated as being of two different types by the
compiler and are incompatible, even if you gave them the same names.

And you can use a struct definition as a variable declaration within a
parameter list:

some_function(struct v {int a; int b;} var) {

but can never call that function, since it expects type "v" which isn't
recognised anywhere except on that parameter list.

I came to this empirically, so correct me if I drew any wrong
conclusions.

Feb 17 '06 #15

P: n/a
"Rob" <io*********@hotmail.com> writes:
Keith Thompson wrote:
> I think it needs to be emphasised how a typedef tells the compiler that
> it is a new type, and is more than merely a #define.
No, a typedef does not create a new type; it merely creates an alias
for an existing type. You can write perfectly good code without using
typedef at all. For example:

struct st {
int a ;
int b;
};

You can then refer to the type simply as "struct st". A typedef
merely creates a second name for the same type.


My point was that typedef tells the compiler to regard it as a type,
e.g. that:
#define i int
and:
typedef int i
are effectively, but not functionally, equivalent.

I used to think that a struct definition could be used interchangeably
with a type keyword:

struct {int a; int b;} var;

But then I found out that this premise is wrong and the above code
useless, since everywhere you explicitly place a struct definition, it
defines a new struct, i.e.:

struct {int a; int b;} var;
struct {int a; int b;} _var;

_var and var are treated as being of two different types by the
compiler and are incompatible, even if you gave them the same names.


(Avoid identifiers starting with underscores.)

You don't need to repeat the struct *definition*. Your declaration above:

struct {int a; int b;} var;

declares an *anonymous* struct type, and a single object of that type.
Anonymous struct types are rarely useful. Just declare it like this:

struct st {
int a;
int b;
};
struct st var1;
struct st var2;

You don't need to repeat the entire struct definition every time you
use it; just use the type's name, "struct st".
And you can use a struct definition as a variable declaration within a
parameter list:

some_function(struct v {int a; int b;} var) {

but can never call that function, since it expects type "v" which isn't
recognised anywhere except on that parameter list.


Right, but there's no point in declaring a function like that. Declare
"struct v" separately, and declare the function as:

void some_function(struct v var);

There's no need for any typedefs.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 17 '06 #16

P: n/a
Rob
Keith Thompson wrote:
There's no need for any typedefs.


You're absolutely right, but I wasn't arguing. There is, however, a
motive for using typedefs: succinctness. Why have a superfluous
"struct" when you can just use the name as is?

Here's how I do it:

struct v_cobject {

struct v_cdata *data;
struct v_ccon *con;
};

typedef struct v_cobject * cobject;

Then where I see the struct keyword, I know it passes by value,
otherwise I know it passes by reference.

Feb 17 '06 #17

P: n/a
Rob
Keith Thompson wrote:
[snip]


Just to clarify, I wasn't confused about the proper use of structs or
typedefs, rather I was making an observation to everyone about the
behaviour of the struct keyword and how it can both define and declare
structs, and how this gives rise to some perfectly legal but perfectly
useless usage of the struct keyword, such as placing a
definition/declaration in a parameter list. (And I was using this
thread as a screening test to see if I had made any errors in said
observation, since it was empirical).

Feb 17 '06 #18

P: n/a
"Rob" <io*********@hotmail.com> writes:
Keith Thompson wrote:
There's no need for any typedefs.


You're absolutely right, but I wasn't arguing. There is, however, a
motive for using typedefs: succinctness. Why have a superfluous
"struct" when you can just use the name as is?

Here's how I do it:

struct v_cobject {

struct v_cdata *data;
struct v_ccon *con;
};

typedef struct v_cobject * cobject;

Then where I see the struct keyword, I know it passes by value,
otherwise I know it passes by reference.


Only if you follow as strict convention of using typedefs for pointers
but not for structs. I've never heard of anyone using such a
convention.

Seeing the "*" in the prototype would tell you much more clearly that
the argument is being passed by reference (actually that a pointer is
being passed by value, with the effect of the pointed-to object being
passed by reference).

How does the name "cobject" tell you that it's a pointer type?

Using the name "cobject" rather than "struct v_cobject*" saves you
some typing, but it makes your code more difficult to read.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Feb 17 '06 #19

P: n/a
Rob

Keith Thompson wrote:
Only if you follow as strict convention of using typedefs for pointers
but not for structs. I've never heard of anyone using such a
convention.

Seeing the "*" in the prototype would tell you much more clearly that
the argument is being passed by reference (actually that a pointer is
being passed by value, with the effect of the pointed-to object being
passed by reference).

How does the name "cobject" tell you that it's a pointer type?
The name doesn't tell it: the fact that it's a non-reserved identifier,
does.

Using the name "cobject" rather than "struct v_cobject*" saves you
some typing, but it makes your code more difficult to read.


Reading code isn't reading English. and I find that reading both
requires a different manner of thinking. When reading code, I want to
read code, not a document. So even if I use conventions that make it
not instantly apparent as to what my code does, I think that in the
long run, if someone takes the time to learn said conventions, they'll
have an easier time grasping the code. My coding philosophy is to
condense things into compact units and use contractions and
abreviations as much as I can get away with, as this makes the code
easier to retain conceptually when thinking about it It's harder to
read at first glance, but easier to recall later.

Anyway, I think I almost drifted off-topic there.

Feb 17 '06 #20

P: n/a
In article <11**********************@g44g2000cwa.googlegroups .com>
Rob <io*********@hotmail.com> wrote:
I think it needs to be emphasised how a typedef tells the compiler that
[this] is a new type ...
It is not the "typedef" keyword that defines the type. It
is the "struct {" pair that does it:
typedef struct {int a; int b;} st;


This means:

1) "typedef" -- set the "typedef flag", so that declarations
of variable are modified.

2) "struct {" -- begin defining a new type, which has no tag
(the compiler just has to make one up, internally).

3) "int a; int b; }" -- the contents of the new type.

4) "st" -- declare a variable, "st" is a variable of type
"struct <magic_compiler_name_00001>", oops wait the
typedef flag is set so make "st" an alias for that type
rather than a variable of that type.

5) ";" -- finish it all off; reset the typedef-flag.

Note that if we write, instead:

struct S { int a; int b; };
typedef struct S st, q, abc, *def, ghi[4];

we will first define a new type (struct S), then define three
aliases for struct S ("st", "q", and "abc"), one alias for a pointer
to that struct S ("def"), and one alias for an array of size 4 of
struct S. We can then do:

void f(struct S arg) {
q local = arg;
def x = &q;

return *x;
}

There is only one underlying user-defined type here, "struct S".
There are lots of aliases for it, but it is the "struct <tag> {"
that created it.

Note also that if you intend to make self-referential or
mutually-referential structures, tags are *absolutely required*:

struct list {
struct list *l_next;
int l_whatever;
/* ... more stuff ... */
};

There is no way to avoid the "struct <tag>" here. You *can* do
this:

typedef struct list list;
struct list {
list *l_next;
int l_whatever;
...
};

but the tag is absolutely, completely, 100% necessary.

Since tags are *sometimes* required, and "typedef" in this
case merely saves keystrokes, I recommend always using tags
and never bothering with the typedefs. There are some valid
"pro-typedef" arguments (which I will not repeat here), but
learning "struct <tag>" is necessary, and using the tag is
never harmful. Might as well Just Do It, as the ads say.

(Note that there is exactly one situation in C where typedef
is in fact *required*, having to do with the va_arg() macro
in <stdlib.h>. The second parameter to va_arg is a type-name,
and it must be one that can be turned into "pointer to <type>"
by adding an asterisk at the end, as by macro expansion. For
most C types, this happens naturally:

int i = va_arg(ap, int); /* int * => pointer to int */
char *cp = va_arg(ap, char *); /* char ** => pointer to (char *) */

but there are a few where it does not:

void (*fp)(int) = va_arg(ap, ???what can you put here???);

The variable "fp" has type "void (*)(int)", or "pointer to
function taking int and returning void". A pointer to that
type is a "pointer to pointer to function taking int and
returning void", which is spelled "void (**)(int)" in C. In
other words, the extra "*" has to go in the middle, not at
the end. So you must insert a typedef, such as:

typedef void (*zorg_function_ptr)(int);
zorg_function_ptr fp = va_arg(ap, zorg_function_ptr);

or:

typedef void zorg_function(int);
zorg_function *fp = va_arg(ap, zorg_function *);

Either of these is valid. When dealing with complicated
function-pointer types, using typedef can make the code more
readable, too. But I find that typedef "damages" C syntax rather
badly, in that what used to be simple and obvious becomes complex
and unobvious:

typedef int x;
int f() { x x; x = 42; return x; }

This is valid C code! There are situations worse than this, in
which it is not at all clear whether some identifier is a typedef-name
or an ordinary identifier; only some entity that has access to the
entire C code, and has parsed it token by token, can tell. C
compilers can figure it out; but human programmers get it wrong.
If you just spell out the "struct" keyword, it becomes simple
and obvious again, and programmers can get it right again.)
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Feb 17 '06 #21

This discussion thread is closed

Replies have been disabled for this discussion.