question about struct??

M

ma0001yu

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
 
F

franto.yu

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 :)
 
R

Roka100

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
 
M

ma0001yu

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
 
K

Keith Thompson

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).
 
S

stathis gotsis

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.
 
S

stathis gotsis

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

Keith Thompson

stathis gotsis said:
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.
 
R

Rob

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.
 
K

Keith Thompson

Rob said:
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>.
 
R

Rob

Keith said:
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.
 
K

Keith Thompson

Rob said:
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.
 
R

Rob

Keith said:
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.
 
R

Rob

Keith said:

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).
 
K

Keith Thompson

Rob said:
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.
 
R

Rob

Keith said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top