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

Typedef structs

P: n/a
Hi all,

I have a question that I'm having difficulty answering. If I have a
struct:

typedef struct my_struct_tag{

struct my_other_struct *other;

} my_struct_tag

(I'm using the struct when declaring other because the definition of
my_other_struct is in another source file.)

Then, I want to access, from a different source file,

my_struct *tmp;
my_other_struct *other_struct;

tmp->other = other_struct;

But, for me, this gives a warning saying that the assignment assigns
different pointer types. If I change the code to:

tmp->other = (struct my_other_struct *)other_struct;

It works, but this is fugly. Is there anyway to assign like the first
method (ie without the cast).

Thanks,

Stephen Henry
Nov 14 '05 #1
Share this Question
Share on Google+
30 Replies


P: n/a
Hi,
I am not sure whether I understand your problem;
if I do
cat os.h struct os {int c;};
cat s.h typedef struct s {struct os *optr;} s_t;
cat test.c

#include "s.h"
#include "os.h"

int main (void)
{
s_t S, *pS;
struct os OS, *pOS;

pOS = &OS;
pS = &S;
pS->optr = pOS;

return 0;
}

then test.c compiles even without warning, irrespective
of the order of the #includes or the fact whether I use
s or s_t for the typedef. (gcc -Wall -ansi -pedantic test.c)

How does you setup differ from the above?
Cheers,
Michael

Nov 14 '05 #2

P: n/a
stephen henry wrote:
Hi all,

I have a question that I'm having difficulty answering. If I have a
struct:

typedef struct my_struct_tag{

struct my_other_struct *other;

} my_struct_tag

(I'm using the struct when declaring other because the definition of
my_other_struct is in another source file.)

Then, I want to access, from a different source file,

my_struct *tmp;
my_other_struct *other_struct;

tmp->other = other_struct;

But, for me, this gives a warning saying that the assignment assigns
different pointer types. If I change the code to:

tmp->other = (struct my_other_struct *)other_struct;

It works, but this is fugly. Is there anyway to assign like the first
method (ie without the cast).


In some times and places, Royalty were considered to
be semi-divine, out of the general run of mankind (no doubt
the Royals encouraged this notion). Since it would be an
unthinkable sacrilege for a mere commoner to lay hands upon
the Royal person, some difficulty arose when there was
sickness or injury at the palace: How could the skilled
medicine man or barber-surgeon conduct a physical examination
of the ailing ruler without touching him?

The solution was to use a stand-in. The untouchable
Majesty would describe his symptoms to a common companion,
and the companion would submit to the specialist's examination
while doing his best to imitate his King's complaint. Given
the state of the medical arts and sciences of the time this
curious practice may not have made much practical difference
in the outcome, but today's doctors and nurses might be just
a wee bit hampered by such a roundabout and indirect custom,
don't you think?

The point of this story is that the pseudo-code you've
shown is just like the stand-in commoner. Is there something
untouchably holy about your actual code that prevents you from
revealing it to our unwashed gaze? Personally, I find it
surpassingly difficult to diagnose your problem when all I get
to see is your proxy. Please post a *complete* and *minimal*
example of *actual* code.

"A King of autocratic power We,
A despot whose tyrannic will is law,
Whose rule is paramount o'er land and sea,
A Presence of unutterable awe!
But though the awe that I inspire
Must shrivel with imperial fire
All foes whom it may chance to touch,
To judge by what I see and hear,
It does not seem to interfere
With popular enjoyment, much."

-- Paramount, Rex

--
Er*********@sun.com

Nov 14 '05 #3

P: n/a
"stephen henry" <st******@yahoo.com> wrote in message
news:84**************************@posting.google.c om...
Hi all,

I have a question that I'm having difficulty answering. If I have a
struct:

typedef struct my_struct_tag{

struct my_other_struct *other;

} my_struct_tag

(I'm using the struct when declaring other because the definition of
my_other_struct is in another source file.)

Then, I want to access, from a different source file,

my_struct *tmp;
my_other_struct *other_struct;
You probably want that line to say:

struct my_other_struct *other_struct;
^^^^^^

That is, you forgot the "struct" keyword.
tmp->other = other_struct;

But, for me, this gives a warning saying that the assignment assigns
different pointer types. If I change the code to:

tmp->other = (struct my_other_struct *)other_struct;

It works, but this is fugly. Is there anyway to assign like the first
method (ie without the cast).

Thanks,

Stephen Henry

--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!

Nov 14 '05 #4

P: n/a
write a "typedef struct my_other_struct *my_other_struct_ptr;"
before you declare the code typedef struct my_struct_tag { ...} ...;

this is doubly-independent definition. C actually allows typedef of a
struct pointer (pointer only) without knowing the definition.

chok
stephen henry wrote:
Hi all,

I have a question that I'm having difficulty answering. If I have a
struct:

typedef struct my_struct_tag{

struct my_other_struct *other;

} my_struct_tag

(I'm using the struct when declaring other because the definition of
my_other_struct is in another source file.)

Then, I want to access, from a different source file,

my_struct *tmp;
my_other_struct *other_struct;

tmp->other = other_struct;

But, for me, this gives a warning saying that the assignment assigns
different pointer types. If I change the code to:

tmp->other = (struct my_other_struct *)other_struct;

It works, but this is fugly. Is there anyway to assign like the first
method (ie without the cast).

Thanks,

Stephen Henry

Nov 14 '05 #5

P: n/a
"doubly-dependent", not "doubly-independent". my bad.

chok

ChokSheak Lau wrote:
write a "typedef struct my_other_struct *my_other_struct_ptr;"
before you declare the code typedef struct my_struct_tag { ...} ...;

this is doubly-independent definition. C actually allows typedef of a
struct pointer (pointer only) without knowing the definition.

chok
stephen henry wrote:
Hi all,

I have a question that I'm having difficulty answering. If I have a
struct:

typedef struct my_struct_tag{

struct my_other_struct *other;

} my_struct_tag

(I'm using the struct when declaring other because the definition of
my_other_struct is in another source file.)

Then, I want to access, from a different source file,
my_struct *tmp;
my_other_struct *other_struct;

tmp->other = other_struct;

But, for me, this gives a warning saying that the assignment assigns
different pointer types. If I change the code to:

tmp->other = (struct my_other_struct *)other_struct;

It works, but this is fugly. Is there anyway to assign like the first
method (ie without the cast).

Thanks,

Stephen Henry

Nov 14 '05 #6

P: n/a
"xarax" <xa***@email.com> wrote in message news:<GP*************@newsread1.news.pas.earthlink .net>...
"stephen henry" <st******@yahoo.com> wrote in message
news:84**************************@posting.google.c om...
Hi all,

I have a question that I'm having difficulty answering. If I have a
struct:

typedef struct my_struct_tag{

struct my_other_struct *other;

} my_struct_tag

(I'm using the struct when declaring other because the definition of
my_other_struct is in another source file.)

Then, I want to access, from a different source file,

my_struct *tmp;
my_other_struct *other_struct;


You probably want that line to say:

struct my_other_struct *other_struct;
^^^^^^

That is, you forgot the "struct" keyword.


Sorry, but I need to clarify somewhat:

Say I have two structures in two seperate files

file1.c
-------

typedef struct my_structure1_tag {

// FOO;

} my_structure1;

file2.c
-------

typedef struct my_structure2_tag {

my_structure1 *my_struct;

} my_structure2;

Now, in order to get file2.c to compile I have to change it so that it
reads:

typedef struct my_structure2_tag {

STRUCT my_structure1 *my_struct;

} my_structure2;

Without the STRUCT i would get a syntax error because the compiler has
not compiled file1.c (which contains the decleration of
my_structure1). By inserting STRUCT I'm essentially saying to the
compiler that my_struct is a pointer to a structure, but I've not yet
defined what that structure actually is yet. What I would like to do,
would be to assigned a newly created my_structure1 as follows:

my_structure1 *structure1;
my_structure2 *structure2;

structure1->my_struct = structure2;

However, because in structure2, my_struct is declares as STRUCT
my_structure1 I have to cast the above assignment to:

structure1->my_struct = (struct my_structure1 *)structure2;

If I don't do this cast, I would get an error saying that I'm
assigning two incompatible pointer types.

So the question is: Is there anyway to compile C such that a structure
can contain another -I believe its called an incomplete- structure
from another, not yet compiled file, without having to cast in the
above manner.

Thanks,

Stephen Henry
Nov 14 '05 #7

P: n/a
Hiho,
file1.c
-------

typedef struct my_structure1_tag {

// FOO;

} my_structure1;
--> file1.h
file2.c
------- #include "file1.h"
typedef struct my_structure2_tag {

my_structure1 *my_struct; without the #include, this type is not known.

} my_structure2;

Now, in order to get file2.c to compile I have to change it so that it
reads:

typedef struct my_structure2_tag {

STRUCT my_structure1 *my_struct; with the #include, both ways are possible; this shoul
read struct. If you want to mark something, use a comment.
} my_structure2;
it would be better, to put that typedef into file2.h (which
includes file1.h).
Without the STRUCT i would get a syntax error because the compiler has
not compiled file1.c (which contains the decleration of
my_structure1). By inserting STRUCT I'm essentially saying to the
compiler that my_struct is a pointer to a structure, but I've not yet
defined what that structure actually is yet. What I would like to do,
would be to assigned a newly created my_structure1 as follows:

my_structure1 *structure1;
my_structure2 *structure2;

structure1->my_struct = structure2;
That is not possible. structure1 only contains // FOO;
However, because in structure2, my_struct is declares as STRUCT
my_structure1 I have to cast the above assignment to:

structure1->my_struct = (struct my_structure1 *)structure2;

If I don't do this cast, I would get an error saying that I'm
assigning two incompatible pointer types.
In which file are you doing this, file1.c, file2.c, or some
yet unknown file3.c?
So the question is: Is there anyway to compile C such that a structure
can contain another -I believe its called an incomplete- structure
from another, not yet compiled file, without having to cast in the
above manner.


If I understand you correctly, try whether
struct mystructure1;

typedef struct my_structure2_tag {
struct my_structure1 *my_struct;
} my_structure2;
helps you.
You have been asked -- directly and indirectly -- to post
a minimal example. Please do not use Pseudo-Code, as this is
likely to produce more confusion than clarifying; apart from
that, yours is broken.

Some notes:
- Use header files for your types, #defines, prototypes and so on.

- Take the time to bring the example down to a minimal example
you can post here (c.f. my first answer to your question).

- Do not tell us what you think happens but give us actual code.
--
Michael

Nov 14 '05 #8

P: n/a
Hiho,
file1.c
-------

typedef struct my_structure1_tag {

// FOO;

} my_structure1;
--> file1.h
file2.c
------- #include "file1.h"
typedef struct my_structure2_tag {

my_structure1 *my_struct; without the #include, this type is not known.

} my_structure2;

Now, in order to get file2.c to compile I have to change it so that it
reads:

typedef struct my_structure2_tag {

STRUCT my_structure1 *my_struct; with the #include, both ways are possible; this shoul
read struct. If you want to mark something, use a comment.
} my_structure2;
it would be better, to put that typedef into file2.h (which
includes file1.h).
Without the STRUCT i would get a syntax error because the compiler has
not compiled file1.c (which contains the decleration of
my_structure1). By inserting STRUCT I'm essentially saying to the
compiler that my_struct is a pointer to a structure, but I've not yet
defined what that structure actually is yet. What I would like to do,
would be to assigned a newly created my_structure1 as follows:

my_structure1 *structure1;
my_structure2 *structure2;

structure1->my_struct = structure2;
That is not possible. structure1 only contains // FOO;
However, because in structure2, my_struct is declares as STRUCT
my_structure1 I have to cast the above assignment to:

structure1->my_struct = (struct my_structure1 *)structure2;

If I don't do this cast, I would get an error saying that I'm
assigning two incompatible pointer types.
In which file are you doing this, file1.c, file2.c, or some
yet unknown file3.c?
So the question is: Is there anyway to compile C such that a structure
can contain another -I believe its called an incomplete- structure
from another, not yet compiled file, without having to cast in the
above manner.


If I understand you correctly, try whether
struct mystructure1;

typedef struct my_structure2_tag {
struct my_structure1 *my_struct;
} my_structure2;
(untested) helps you.
You have been asked -- directly and indirectly -- to post
a minimal example. Please do not use Pseudo-Code, as this is
likely to produce more confusion than clarifying; apart from
that, yours is broken.

Some notes:
- Use header files for your types, #defines, prototypes and so on.

- Take the time to bring the example down to a minimal example
you can post here (c.f. my first answer to your question).

- Do not tell us what you think happens but give us actual code.
--
Michael

Nov 14 '05 #9

P: n/a
In article <news:84**************************@posting.google. com>
stephen henry <st******@yahoo.com> wrote:
Sorry, but I need to clarify somewhat:


[more sample code that is definitely not the actual code]

Suppose you were a car mechanic and I drove up in a vehicle and
said "my car isn't working right; it won't start." You might wonder
how I got the car to you. What would you think if I told you: "Oh,
this isn't my car, this is my neighbor's car, but we have the same
brand of vehicle. You should be able to fix mine by looking at
his, right?"

:-)

In any case, I have a method I recommend. Stop using typedef for
structs.

Just plain stop using it. You do not NEED it, and what it does is
rarely what most beginning or even intermediate-level C programmers
expect. Use structure tags, and most of your problems will go
away.
--
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.
Nov 14 '05 #10

P: n/a
Chris Torek <no****@torek.net> writes:
In any case, I have a method I recommend. Stop using typedef for
structs.

Just plain stop using it. You do not NEED it, and what it does is
rarely what most beginning or even intermediate-level C programmers
expect. Use structure tags, and most of your problems will go
away.


Usually I find myself in agreement with Chris Torek's advice;
in this case however I think the advice given is somewhat
shortsighted.

Right from the very beginning, C programmers should be taught
to follow the pattern
typedef struct some_type_name_struct_tag some_type_name;
struct some_type_name_struct_tag {

/* ... definition goes here ... */

};
and elsewhere always use 'some_type_name' to refer to the structure
type.

I don't mean to suggest that they follow the pattern blindly; there
should be explanation of the two pieces. But the amount of
explanation needed isn't that much, and the development practice is a
good one to be in the habit of following. Surely at some point there
will also be a need to explain about 'struct' tags and their separate
namespace, and so forth, but the pattern above is helpful much more
often than it's harmful - it's better to learn it earlier rather than
later.
Nov 14 '05 #11

P: n/a
Tim Rentsch wrote:

Chris Torek <no****@torek.net> writes:
In any case, I have a method I recommend. Stop using typedef for
structs.

Just plain stop using it. You do not NEED it, and what it does is
rarely what most beginning or even intermediate-level C programmers
expect. Use structure tags, and most of your problems will go
away.


Usually I find myself in agreement with Chris Torek's advice;
in this case however I think the advice given is somewhat
shortsighted.

Right from the very beginning, C programmers should be taught
to follow the pattern

typedef struct some_type_name_struct_tag some_type_name;

struct some_type_name_struct_tag {

/* ... definition goes here ... */

};

and elsewhere always use 'some_type_name' to refer to the structure
type.

I don't mean to suggest that they follow the pattern blindly; there
should be explanation of the two pieces. But the amount of
explanation needed isn't that much, and the development practice is a
good one to be in the habit of following. Surely at some point there
will also be a need to explain about 'struct' tags and their separate
namespace, and so forth, but the pattern above is helpful much more
often than it's harmful - it's better to learn it earlier rather than
later.


Your explanation is missing the part about why it's good
to typedef a struct. I don't see any point in doing it.
Why is
some_type_name object;
superior to
struct some_type_name_struct_tag object;
?

--
pete
Nov 14 '05 #12

P: n/a
>> Chris Torek <no****@torek.net> writes:
In any case, I have a method I recommend. Stop using typedef for
structs. ...
Tim Rentsch wrote:
Usually I find myself in agreement with Chris Torek's advice;
in this case however I think the advice given is somewhat
shortsighted.

Right from the very beginning, C programmers should be taught
to follow the pattern

typedef struct some_type_name_struct_tag some_type_name;

struct some_type_name_struct_tag {

/* ... definition goes here ... */

};

and elsewhere always use 'some_type_name' to refer to the structure
type.

This is what I recommend as an alternative *if* one is stubbornly
insistent on using typedefs.
I don't mean to suggest that they follow the pattern blindly; there
should be explanation of the two pieces.


And indeed, in the past, I have done that (feel free to DejaGoogle
search for such articles). Sometimes I have less time to post,
though. :-)

In article <news:41***********@mindspring.com>
pete <pf*****@mindspring.com> wrote:Your explanation is missing the part about why it's good
to typedef a struct. I don't see any point in doing it.
Why is
some_type_name object;
superior to
struct some_type_name_struct_tag object;
?


I do not believe it is, myself, but I acknowledge that this is a
matter of opinion rather than fact.
--
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.
Nov 14 '05 #13

P: n/a
pete <pf*****@mindspring.com> writes:
Tim Rentsch wrote:

Right from the very beginning, C programmers should be taught
to follow the pattern

typedef struct some_type_name_struct_tag some_type_name;

struct some_type_name_struct_tag {

/* ... definition goes here ... */

};

and elsewhere always use 'some_type_name' to refer to the structure
type.


Your explanation is missing the part about why it's good
to typedef a struct. I don't see any point in doing it.
Why is
some_type_name object;
superior to
struct some_type_name_struct_tag object;
?


Ahh, this is a good question. I would offer several reasons:

1. (minor) Slight economy of expression - shorter to omit 'struct'.

2. Using a typedef'ed name gives greater flexibility in the choice
of type - if later we want some_type_name to be a 'union' or 'int'
or 'enum', less of the program will need to change as a result.

3. Greater safety - if the type is defined in a header file (as it
very likely may be), and the header file is not #include'ed, using

some_type_name *x;

will produce an error, whereas

struct some_type_name_struct_tag *x;

need no produce any diagnostic at all. Sometimes the second case is
perfectly easy to figure out, but the first case is *always* easy to
figure out.

4. Natural extension to opaque types - a commonly useful pattern is to
pass pointers where the pointer type is public but the type being
pointed at is private; if someone is used to separate definitions for
the type name and the 'struct' members, that leap will seem more
natural than if they aren't - just move the typedef to a public header
file and keep the struct definition local. In a sense this point is
similar to point (2), but there is also something else - for didactic
reasons we would like to be able introduce opaque types early in the
educational cycle, and having separately defined type names makes it
easier both to make use of opaque (pointer) types and to explain some
mechanics about how to express opaque types in C.

In connection with point 4, for a type that is opaque and will always
be accessed via pointers, there is nothing wrong with defining a
pointer type rather than an instance type as the defined type name.
(Of course it's important to get the conventions right so which is
which is always clear.)
Forgive me for not listing these earlier - I'd sort of assumed without
thinking about it that most long time C developers would be aware of
all of these already.

Nov 14 '05 #14

P: n/a
Chris Torek <no****@torek.net> writes:
In article <news:41***********@mindspring.com>
pete <pf*****@mindspring.com> wrote:
Your explanation is missing the part about why it's good
to typedef a struct. I don't see any point in doing it.
Why is
some_type_name object;
superior to
struct some_type_name_struct_tag object;
?


I do not believe it is, myself, but I acknowledge that this is a
matter of opinion rather than fact.


To be fair here, I should say that in addition to some advantages that
the first form has (which I posted separately), there also are some
advantages to the second form. I think everyone would agree that
there are some advantages to each approach; where opinions might
differ is on the relative merits of the two sets of advantages. My
other posting didn't try to address either the advantages of the
second form or the question of the relative merits of the two
approaches.
Nov 14 '05 #15

P: n/a
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
[...]
Right from the very beginning, C programmers should be taught
to follow the pattern
typedef struct some_type_name_struct_tag some_type_name;
struct some_type_name_struct_tag {

/* ... definition goes here ... */

};
and elsewhere always use 'some_type_name' to refer to the structure
type.


The counterargument is that it hides (or attempts to hide) information
that shouldn't be hidden.

Assigning a simple name to a complicated type can be useful if the
goal is data abstraction. It can encourage the programmer to focus on
the operations that are appropriate to the type, without worrying
about the lower level operations that may not be. An example of this
is size_t; the name doesn't tell you whether it's signed, unsigned, or
floating-point, and the programmer shouldn't write code that depends
on such details.

For a struct type, however, there's often not much you can do with the
type without knowing that it's a struct. If you're going to refer to
members, you obviously *have* to know that it's a struct. (The type
FILE in <stdio.h> is an exception to this; the user of the interface
can use it only via pointers, and there are no portably defined
members.)

A good rule of thumb is probably:

If you can sensibly hide from the user the fact that a type is a
struct, use a typedef (such as FILE in <stdio.h>). If not, don't, and
let the user refer to the type as "struct foo" (such as struct tm in
<time.h>). The latter is probably more common.

(Personally, I'm not as opposed to gratuitous typedefs for structs as
some people are, but I understand the arguments.)

--
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.
Nov 14 '05 #16

P: n/a
Keith Thompson wrote:
Assigning a simple name to a complicated type can be useful if the
goal is data abstraction. It can encourage the programmer to focus on
the operations that are appropriate to the type, without worrying
about the lower level operations that may not be. An example of this
is size_t; the name doesn't tell you whether it's signed, unsigned, or
floating-point, and the programmer shouldn't write code that depends
on such details.


The programmer can depend on size_t being an unsigned integer type.

--
pete
Nov 14 '05 #17

P: n/a
pete <pf*****@mindspring.com> writes:
Keith Thompson wrote:
Assigning a simple name to a complicated type can be useful if the
goal is data abstraction. It can encourage the programmer to focus on
the operations that are appropriate to the type, without worrying
about the lower level operations that may not be. An example of this
is size_t; the name doesn't tell you whether it's signed, unsigned, or
floating-point, and the programmer shouldn't write code that depends
on such details.


The programmer can depend on size_t being an unsigned integer type.


Sorry, that was a braino. I meant time_t, not size_t.

But that raises a good point. C's type system isn't as expressive as
it could be (which is not to say that it *should* be as expressive as
it could be). You can have a type name that doesn't tell you anything
about a type (foo_t), or one that tells you only that it's a struct
(struct foo), but there's no syntax for specifying that time_t is an
arithmetic type, or that size_t is an unsigned integer type without
saying which one. In many cases, you have to depend on documentation
to let the programmer know what properties can be depended on.

Any convention about whether to use "struct foo" or a typedef is going
to be an imperfect compromise.

--
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.
Nov 14 '05 #18

P: n/a
pete <pf*****@mindspring.com> writes:
Your explanation is missing the part about why it's good
to typedef a struct. I don't see any point in doing it.
Why is
some_type_name object;
superior to
struct some_type_name_struct_tag object;


I generally do not typedef structs. However, occasionally I run
into an awkward situation where I want one struct to be
interchangeable for another. For example, suppose one already
has a linked list whose element is a `struct list_elem'. If one
then wishes to implement a hash table with chaining it would be
convenient for abstraction purposes to declare `struct hash_elem'
as an alias for `struct list_elem'. Unfortunately, this simply
cannot be done in C. `#define hash_elem list_elem' is not
acceptable because it pollutes the global namespace, not just the
tag namespace. A `typedef' is a reasonable way out.
--
"It would be a much better example of undefined behavior
if the behavior were undefined."
--Michael Rubenstein
Nov 14 '05 #19

P: n/a
Keith Thompson <ks***@mib.org> writes:
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
[...]
Right from the very beginning, C programmers should be taught
to follow the pattern
typedef struct some_type_name_struct_tag some_type_name;
struct some_type_name_struct_tag {

/* ... definition goes here ... */

};
and elsewhere always use 'some_type_name' to refer to the structure
type.
The counterargument is that it hides (or attempts to hide) information
that shouldn't be hidden.

^^^^^^^^^
What reasons would you offer that it shouldn't be hidden? In a separate
article I responded to another poster's query and listed some advantages
of the separate type name approach. Could one of the just-use-structs
advocates respond and list some principal advantages of not using
a separate type name?

Assigning a simple name to a complicated type can be useful if the
goal is data abstraction.
More importantly, information hiding. See the well-known papers
by David Parnas. Also Brooks's "Mythical Man Month", 20th Anniversary
Edition.

For a struct type, however, there's often not much you can do with the
type without knowing that it's a struct. [...]
Here's a list of things that can be done with (most) complete types,
without knowing what type they are:

1. Declare variables of the type (and arrays-of and pointers-to same)
2. Assign values (and accept parameters and return results)
3. Pass values to functions, and get values back as results
4. Take the address with '&'
5. Use 'sizeof' to get the size, which allows allocation with 'malloc()'

In C99 that might be all complete object types - I'm unsure about the status
in C99 of array assignment. Note that the list is more than enough to allow
useful work to get done, as the 'FILE' example demonstrates.

A good rule of thumb is probably:

[...]
Let me suggest this rule: Always use typedefs for structs, except in
cases where the advantages of not using them outweigh the advantages
of using them. I've yet to see a statement in this thread about what
the advantages of not using typedefs for structs are, let alone a
comparison of the different advantages for the two approaches.

(Personally, I'm not as opposed to gratuitous typedefs for structs as
some people are, but I understand the arguments.)


Keith, I'm disappointed. This kind of rhetoric - a content-free
statement giving a "non-argument" argument, including the emotional
hook word "gratuitous" - should be below you.
Nov 14 '05 #20

P: n/a
Tim Rentsch wrote:
.... snip ...
Let me suggest this rule: Always use typedefs for structs, except in
cases where the advantages of not using them outweigh the advantages
of using them. I've yet to see a statement in this thread about what
the advantages of not using typedefs for structs are, let alone a
comparison of the different advantages for the two approaches.


I think the general feeling is not to hide the fact that an entity
is a struct, and that use implies selecting fields. Of coarse
this doesn't apply when you want to export an anonymous structure
and provide routines for operating on its fields. In that case a
typedef is probably the preferred method.

--
"Churchill and Bush can both be considered wartime leaders, just
as Secretariat and Mr Ed were both horses." - James Rhodes.
"We have always known that heedless self-interest was bad
morals. We now know that it is bad economics" - FDR
Nov 14 '05 #21

P: n/a
Tim Rentsch <tx*@alumnus.caltech.edu> writes:
Keith Thompson <ks***@mib.org> writes:

[...]
The counterargument is that it hides (or attempts to hide) information
that shouldn't be hidden.

^^^^^^^^^
What reasons would you offer that it shouldn't be hidden? In a separate
article I responded to another poster's query and listed some advantages
of the separate type name approach. Could one of the just-use-structs
advocates respond and list some principal advantages of not using
a separate type name?


I'm probably not one of the "just-use-structs advocates", but I'll
respond anyway.

I certainly have no objection to abstract types, and they should
probably be used more often than they are, but not all types are
abstract.

I gave several examples in my previous post. To repeat one of them,
the type "struct tm", declared in <time.h>, is visibly a struct.
Declaring a typedef, say "typedef struct tm { ... } tm;", and
declaring an object as
tm obj;
rather than as
struct tm obj;
doesn't really hide anything when you're referring to "obj.tm_sec"
anyway.

If struct tm were an abstract data type, with no defined members and a
purely functional interface, the typedef would make perfect sense.

Personally, I see the debate as something similar to the controversies
over brace style. Most people have their own preferences, and many
people feel quite strongly about them (perhaps with good reason), but
we all had better be able to cope with code written in styles other
than the one we like.

[...]
(Personally, I'm not as opposed to gratuitous typedefs for structs as
some people are, but I understand the arguments.)


Keith, I'm disappointed. This kind of rhetoric - a content-free
statement giving a "non-argument" argument, including the emotional
hook word "gratuitous" - should be below you.


Huh?

The statement in parentheses wasn't meant to be an argument, just a
disclaimer. Feel free to read "gratuitous" as "not strictly
necessary" if it will make you happy. (I don't see "gratuitous" as a
purely pejorative term.)

--
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.
Nov 14 '05 #22

P: n/a

In article <kf*************@alumnus.caltech.edu>, Tim Rentsch <tx*@alumnus.caltech.edu> writes:
pete <pf*****@mindspring.com> writes:
Your explanation is missing the part about why it's good
to typedef a struct.
Ahh, this is a good question.


Indeed, it is *the* question, since you were responding to Chris'
recommendation against typedef'ing structs, and since - contrary
to your blithe (a less charitable reader might call it arrogant)
assumption in another post that they should be obvious to any
experienced C programmer - your justifications for the practice
are neither obvious nor obviously true.
I would offer several reasons:

1. (minor) Slight economy of expression - shorter to omit 'struct'.
Economy of expression is not an absolute good. In fact, it's
arguably done significant damage to software on the whole, due to
the proliferation of code that's difficult to maintain due to
unnecessary terseness.

Moreover, it discards information, which makes the code harder to
understand, which is another obstacle to maintenance. Hiding
information in source code is only good when abstraction is
merited; and in such cases, it's redundant to uphold information-
hiding in itself as an advantage.
2. Using a typedef'ed name gives greater flexibility in the choice
of type - if later we want some_type_name to be a 'union' or 'int'
or 'enum', less of the program will need to change as a result.
Very little less, in most cases. When I write code that operates
on a struct, and that struct subsequently becomes a union or an
int or an enum, chances are excellent that the code itself will
have to change. If I am not hiding the type's category behind a
typedef, the implementation will helpfully notify me if I should
neglect to make such changes. If I am, there are plausible
situations where it will not.
3. Greater safety - if the type is defined in a header file (as it
very likely may be), and the header file is not #include'ed, using

some_type_name *x;

will produce an error, whereas

struct some_type_name_struct_tag *x;

need no produce any diagnostic at all. Sometimes the second case is
perfectly easy to figure out, but the first case is *always* easy to
figure out.
This strikes me as far less common than the previous case. If
the type is defined in a header file, then code which should be
including that header probably needs it for other reasons (eg to
supply prototypes for the API associated with the abstract data
type you're hypothesizing - what else are you going to do with a
pointer to an incomplete type, than pass it to some function
which understands it?).

Further, since all struct pointers have the same alignment and
representation, and since your example is only meaningful when
"struct some_type_name_struct_tag" is an incomplete type, I don't see
what damage is done in the case where the translation unit
accidentally declares its own "struct some_type_name_struct_tag *x".
In fact, unless I am mistake, the only effect of such a declaration
is to place "some_type_name_struct_tag" into the struct tag namespace
and to declare a variable x which can be used semantically to hold any
struct's address (syntactic constraints notwithstanding).
4. Natural extension to opaque types


Opaque data types is one of only two cases where I can see any
advantage to typedef'ing structs. (The other is for passing to
va_arg, which is not compatible with the full C type syntax and so
sometimes requires "helper" typedefs.)

Even in the case of opaque data types, however, there are times when
the struct tag is more useful, I would argue. I like to apply some
fairly strict rules for coupling and information sharing among the
modules (translation units) of many of my projects. In many cases
some use pointers to types that are incomplete to them but complete
for other modules. In this case there's no benefit to hiding the
type category; both opaque and completed types are available to all
the developers who might maintain the code.

--
Michael Wojcik mi************@microfocus.com

See who I'm! -- Jackie Chan and unknown subtitler, _Dragons Forever_
Nov 14 '05 #23

P: n/a

In article <kf*************@alumnus.caltech.edu>, Tim Rentsch <tx*@alumnus.caltech.edu> writes:
Keith Thompson <ks***@mib.org> writes:

What reasons would you offer that it shouldn't be hidden?
I've provided one already in another post: it gives the
implementation more power to catch errors if the type category
should change (an example you raised as an advantage of hiding
the category). Frankly, I think the fact that using the struct
tag provides even a small amount of additional information to
maintenance programmers is in itself a significant advantage.
Assigning a simple name to a complicated type can be useful if the
goal is data abstraction.


More importantly, information hiding.


Which differs from data abstraction how, in this case?
See the well-known papers
by David Parnas. Also Brooks's "Mythical Man Month", 20th Anniversary
Edition.
Don't you think that's a bit weak as an appeal to authority? See
*what* in Parnas or Brooks?
Let me suggest this rule: Always use typedefs for structs, except in
cases where the advantages of not using them outweigh the advantages
of using them.


Sure. Here's mine: Never use typedefs for structs, except in cases
where the advantages of using them outweigh the advantages of not
using them.
(Personally, I'm not as opposed to gratuitous typedefs for structs as
some people are, but I understand the arguments.)


Keith, I'm disappointed. This kind of rhetoric - a content-free
statement giving a "non-argument" argument, including the emotional
hook word "gratuitous" - should be below you.


Is English not your first language? "gratuitous" has a well-
defined denotation, and while it may be an "emotional hook word"
for you, it's quite meaningful for many of us. And I'm puzzled
that you consider this statement an "argument" at all on Keith's
part, since it's clearly parenthetical (even without the
parentheses) and explicitly expresses an opinion.

And it's an opinion *in support of your side*.

And *all* argumentation is rhetoric. Perhaps you should consult
a dictionary on the denotation of that term, too.

And if you're going to get your feathers ruffled by imagined
slights like that, I don't see you lasting too long here, where
regulars are likely to defend their opinions vigorously.

And, finally, with the single exception of use with va_arg, I am
unable to think of a use of typedef which is not gratuitous. Can
you provide an example?

--
Michael Wojcik mi************@microfocus.com

This is a "rubbering action game," a 2D platformer where you control a
girl equipped with an elastic rope with a fishing hook at the end.
-- review of _Umihara Kawase Shun_ for the Sony Playstation
Nov 14 '05 #24

P: n/a
In article <news:ch*********@news2.newsguy.com>
Michael Wojcik <mw*****@newsguy.com> wrote:
Opaque data types is one of only two cases where I can see any
advantage to typedef'ing structs. (The other is for passing to
va_arg, which is not compatible with the full C type syntax and so
sometimes requires "helper" typedefs.)


Indeed, these are the two primary "pro-typedef" cases for me, as
well. (Of course, va_arg really does *require* typedefs at times,
as you note.)

There is another "pro-typedef" case not involving structures,
having to do with naming. Abstraction and naming seem to me to
go hand-in-hand, and one way to make something difficult become
comprehensible is to name it. The sloganeering might go: "Name
it to tame it." :-)

I think it can be argued (but I do not have time to pursue this
right now) that this "naming argument" actually covers the opaque
data type situation. In languages other than C, where "bare" type
declarations are (or can be) type-creating operations (e.g., Ada
has both "sub-typing" and "separate-typing"), such abstractions
with their names may cover any type. C is a bit peculiar in that
to create a *new* type, we have to use struct (or union or enum,
but struct is the general version). To make a new datatype that
contains only an integer, we have to create a whole structure:

struct T1 { int value; };
struct T2 { int value; };

Now types T1 and T2 are different, even though they both just have
a single "int" element named value. You cannot mix up the types
without getting a compiler diagnostic.

Until C99, it was impossible in general (in "full generality" at
least) to hide the fact that some typedef'ed alias actually covered
a structure. Consider:

typedef
#include "secret.h"
alias_t;

where "secret.h" contains some valid token sequence that results
in making "alias_t" an alias for some data type, possibly a struct
(or union or enum) but perhaps a scalar or pointer.

Now suppose we see this:

#include "secret2.h" /* defines SOME_CONSTANT of type alias_t */

void somefunc(alias_t);

void f(void) {
somefunc(SOME_CONSTANT);
}

This immediately tells us, in C89, that alias_t is *not* a struct.
There is no way to pass an actual constant of some "struct" type.
(Admittedly, one can "cheat" -- secret2.h might have "const struct
tag FAKE_CONSTANT = { ... };" and then #define SOME_CONSTANT to
expand to FAKE_CONSTANT. This *almost* completely hides it --
#ifdef works right for instance -- except that we can now compute
&SOME_CONSTANT.)

C99 fixes this by adding anonymous aggregates:

#define SOME_CONSTANT ((const struct tag){ ... })

In practice, in a lot of real code one sees:

typedef /* not-very-secret stuff */ alias_t;
...
void somefunc(alias_t);
void f(void) {
somefunc(32.4); /* exposed! alias_t is some floating-pt type */
}

so that the abstractions are "leaky".

Given leaky abstractions, and C's syntax, I prefer to just spell
out the "struct" keyword, most of the time.
--
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.
Nov 14 '05 #25

P: n/a
mw*****@newsguy.com (Michael Wojcik) writes:
In article <kf*************@alumnus.caltech.edu>, Tim Rentsch
<tx*@alumnus.caltech.edu> writes:

[...]
4. Natural extension to opaque types


Opaque data types is one of only two cases where I can see any
advantage to typedef'ing structs. (The other is for passing to
va_arg, which is not compatible with the full C type syntax and so
sometimes requires "helper" typedefs.)


Sometimes it does, but not in the case of a simple "struct foo" type
name.

The requirement for the type argument to va_arg is (C99 7.15.1.1,
underscores denoting italics):

The parameter _type_ shall be a type name specified such that the
type of a pointer to an object that has the specified type can be
obtained simply by postfixing a * to _type_.

C90 has identical wording.

The type of a pointer to "struct foo" is just "struct foo *"; there's
no need for a typedef.

--
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.
Nov 14 '05 #26

P: n/a

In article <ln************@nuthaus.mib.org>, Keith Thompson <ks***@mib.org> writes:
mw*****@newsguy.com (Michael Wojcik) writes:
Opaque data types is one of only two cases where I can see any
advantage to typedef'ing structs. (The other is for passing to
va_arg, which is not compatible with the full C type syntax and so
sometimes requires "helper" typedefs.)


Sometimes it does, but not in the case of a simple "struct foo" type
name.


Right. I meant to write that I thought typedef's in general were
only useful for creating opaque data types and for passing complex
types to va_arg; the reference to typedef'ing structs in particular
came from an earlier edit. Thanks for supplying the clarification.

I don't believe I've actually ever passed a sufficently-complex type
to a variadic function to need a typedef, in fact.

--
Michael Wojcik mi************@microfocus.com

You have Sun saying, "Who needs Linux? We have Solaris." You have
Microsoft saying, "Who needs Linux? We have Windows 2000." Then you
have IBM saying, "I think we all need Linux." Only the greatest
sinners know how to really repent. -- John Patrick, IBM VP
Nov 14 '05 #27

P: n/a
On 27 Aug 2004 12:13:47 -0700, st******@yahoo.com (stephen henry)
wrote:
file1.c
-------

typedef struct my_structure1_tag {

// FOO;

} my_structure1;

file2.c
-------

typedef struct my_structure2_tag {

my_structure1 *my_struct;

} my_structure2;

Now, in order to get file2.c to compile I have to change it so that it
reads:

typedef struct my_structure2_tag {

STRUCT my_structure1 *my_struct;

} my_structure2;

Without the STRUCT i would get a syntax error because the compiler has
not compiled file1.c <snip>


Right. But when/if you do get that declaration, it's of struct
my_structure1_tag, not struct my_structure1.Those are different, which
is why your compiler diagnoses the type as incompatible.

One convenient way to fix this is to use the same name for the struct
(or union) tag and the typedef. This *is* legal; they are in separate
namespaces. <OT> In C++ this is effectively done for you; the tag is
by default a typename so </> if you want to use the same practices,
and maybe even some of the same code, in these two related but
different languages this is an easy one to make compatible.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #28

P: n/a
Could someone explain why you need the struct keyword at all when declaring
a variable :

The code below works ok and I've declared my_struct without using the struct
keyword.

#include <stdio.h>
struct test_struct
{
int a;
int b;
};
void main()
{
test_struct my_struct;

printf("hello world\n");
}
"xarax" <xa***@email.com> wrote in message
news:GP*************@newsread1.news.pas.earthlink. net...
"stephen henry" <st******@yahoo.com> wrote in message
news:84**************************@posting.google.c om...
Hi all,

I have a question that I'm having difficulty answering. If I have a
struct:

typedef struct my_struct_tag{

struct my_other_struct *other;

} my_struct_tag

(I'm using the struct when declaring other because the definition of
my_other_struct is in another source file.)

Then, I want to access, from a different source file,

my_struct *tmp;
my_other_struct *other_struct;


You probably want that line to say:

struct my_other_struct *other_struct;
^^^^^^

That is, you forgot the "struct" keyword.
tmp->other = other_struct;

But, for me, this gives a warning saying that the assignment assigns
different pointer types. If I change the code to:

tmp->other = (struct my_other_struct *)other_struct;

It works, but this is fugly. Is there anyway to assign like the first
method (ie without the cast).

Thanks,

Stephen Henry

--
----------------------------
Jeffrey D. Smith
Farsight Systems Corporation
24 BURLINGTON DRIVE
LONGMONT, CO 80501-6906
http://www.farsight-systems.com
z/Debug debugs your Systems/C programs running on IBM z/OS for FREE!

Nov 14 '05 #29

P: n/a


Steve Lambert wrote:
Could someone explain why you need the struct keyword at all when declaring
a variable :

You need it because the Standard for the C Language, ISO/IEC 9899:1999,
requires it.

The code below works ok and I've declared my_struct without using the struct
keyword.

My guess is that you are compiling with C++ Compiler. I believe
the keyword is not needed in C++ and function main returns type
void. In C, the keyword is required and function main returns type
int. The C Language is defined by the Standard that I mentioned above
and not by your compiler.
#include <stdio.h>
struct test_struct
{
int a;
int b;
};
void main()
{
test_struct my_struct;

printf("hello world\n");
}


--
Al Bowers
Tampa, Fl USA
mailto: xa******@myrapidsys.com (remove the x to send email)
http://www.geocities.com/abowers822/

Nov 14 '05 #30

P: n/a
Al Bowers <xa******@rapidsys.com> writes:
[...]
My guess is that you are compiling with C++ Compiler. I believe
the keyword is not needed in C++ and function main returns type
void. In C, the keyword is required and function main returns type
int. The C Language is defined by the Standard that I mentioned above
and not by your compiler.


main returns int in both C and C++. (C++ is actually more strict than
C; both allow implementation-defined declarations of main, but only C
those implementation-defined declarations to have a return type other
than int.)

--
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.
Nov 14 '05 #31

This discussion thread is closed

Replies have been disabled for this discussion.