473,473 Members | 2,320 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

question about struct??

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
20 2061
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
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
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
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
Thank you very much! :p

Feb 15 '06 #6
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
<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

"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
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
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
"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
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
"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
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
"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
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
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
"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
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
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 (40°39.22'N, 111°50.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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: kazack | last post by:
Hi all it's me again with another question as I got further in my book. The chapter I am in covers structres, abstract data and classes. I only read through to the end of the coverage on...
23
by: Serve La | last post by:
When I write a medium to large sized C application I tend to create structures first, then makeStruct and freeStruct functions that dynamically allocate/free the struct and then I create a bunch of...
1
by: rahul8143 | last post by:
hello, In kernel source code there is ip_fragment.c file my question is regarding pointer function and casting for that look at required snippet from that file There is structure defined for...
16
by: Duncan Mole | last post by:
Hi, This is probably an easy one but it iy first bit of p/invoke. I am trying to use the following C struct in a call: typedef struct { BYTE SRB_Cmd; BYTE SRB_Status, BYTE ...
5
by: Brian | last post by:
I am "learning" C# and have run into a problem that, though I can work around it, I would like to know what the *right* way to handle the issue is. I have created an "Info" struct and assigned...
19
by: lawtrevor | last post by:
I have a question regarding the use of free() based on some code I need to decipher: { struct A {<A fields>}; struct B {<A fields+ <Bfields>}; typedef struct A Aobj; typedef struct B Bobj;
3
by: kkk | last post by:
I am practicing LRU by writing a simulating c programme, but encounter a problem. The problem is when a page hit occurred (simulated process request (contains requested page) a page, which has...
21
by: Chad | last post by:
At the following url http://c-faq.com/lib/qsort2.html, they have the following Q: Now I'm trying to sort an array of structures with qsort. My comparison function takes pointers to structures,...
4
by: hugo.arregui | last post by:
Hi! I have two struts like that: struct { int num; int num2; struct b arrayOfB; } a;
5
by: =?Utf-8?B?SmVzc2ljYQ==?= | last post by:
Hello, I have a pInvoke question. This is the C function that is exported from one of the C dll, extern __declspec(dllexport) IM_RET_CODE ST_import (IM_MODE mode, char *filename,...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.