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

typedef, structs, and pointers

P: n/a
Can someone please explain why the following is not possible?
typedef foobar {
int x;
foobar *next; /* why can't we do this? */
};
Thanks
Jul 18 '06 #1
Share this Question
Share on Google+
17 Replies


P: n/a
Steve Carter <st***@127.0.0.1wrote:
>Can someone please explain why the following is not possible?
typedef foobar {
int x;
foobar *next; /* why can't we do this? */
};
Thanks
Missing 'struct' - Missing new name for typedef.

You probably want something like this:

typedef struct foobar {
int x;
struct foobar *next;
} FooBar;

Then you can declare new structures using

FooBar fb;

fb.next = ...; etc.

Jul 18 '06 #2

P: n/a
Roberto Waltman wrote:
Missing 'struct' - Missing new name for typedef.

Oops, I forgot to put 'struct' in (though, I meant to). I still don't
understand why you can't use the typedef name for 'next' pointer,
though.
typedef struct foobar {
int x;
foobar *next;
};

Jul 18 '06 #3

P: n/a
In article <e9**********@nntp.aioe.org>, Steve Carter <st***@127.0.0.1wrote:
>Can someone please explain why the following is not possible?
>typedef foobar {
int x;
foobar *next; /* why can't we do this? */
};
"Because I say so" ;-)

The typename for the typedef is not considered to exist until
the end of the declaration, and the people who designed C did not
happen to design in forward references for this case. They did
design in forward references for the struct case. I cannot think at
the moment of any technical reason that would block implementing
forward references for typedef, but -perhaps- it would make the
parser noticably trickier.
--
Programming is what happens while you're busy making other plans.
Jul 18 '06 #4

P: n/a
Steve Carter <st***@127.0.0.1writes:
Oops, I forgot to put 'struct' in (though, I meant to). I still don't
understand why you can't use the typedef name for 'next' pointer,
though.
typedef struct foobar {
int x;
foobar *next;
};
No typedef name is defined here. The typedef keyword is
superfluous.
--
"Your correction is 100% correct and 0% helpful. Well done!"
--Richard Heathfield
Jul 18 '06 #5

P: n/a


Steve Carter wrote On 07/18/06 15:10,:
Roberto Waltman wrote:

>>Missing 'struct' - Missing new name for typedef.

Oops, I forgot to put 'struct' in (though, I meant to). I still don't
understand why you can't use the typedef name for 'next' pointer,
though.
typedef struct foobar {
int x;
foobar *next;
};
What typedef name? (Hint: Look closely at the tiny
space between the closing curly bracket and the semicolon.
How many names do you see there?)

If you changed the code to:

typedef struct foobar {
int x;
foobar *next;
} foobar;

.... you'd be closer, but it would still be no good. The
problem is that `foobar' isn't known as a name until the
fourth line, but the code tries to use the name in the
third. Some languages "look ahead" that way, but C is
not among them.

If you're confused by the multiple different apperances
of the string `foobar', change one of them:

typedef struct barfoo {
int x;
foobar next;
} foobar;

.... which has the same flaw as the previous rewrite, but
perhaps more obviously.

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

Jul 18 '06 #6

P: n/a
Steve Carter <st***@127.0.0.1wrote:
>Roberto Waltman wrote:
>Missing 'struct' - Missing new name for typedef.

Oops, I forgot to put 'struct' in (though, I meant to). I still don't
understand why you can't use the typedef name for 'next' pointer,
though.

typedef struct foobar {
int x;
foobar *next;
};
(At least) Two reasons:

(a) A typedef creates a new name for an existing type. In your
example, the type is "struct foobar". The new name is missing
altogether.

(b) The new name can be used only after the typedef has been
processed. (Not inside the declaration itself.)
typedef struct foobar {
int x;
struct foobar *next;
} FooBar; /* missing new name inserted here */
typedef struct newbar {
int x;
FooBar *there; /* OK, FooBar was declared before */
NewBar *next; /* Error, NewBar declaration not completed */
} NewBar;
Jul 18 '06 #7

P: n/a
Steve Carter wrote:
Can someone please explain why the following is not possible?
typedef foobar {
int x;
foobar *next; /* why can't we do this? */
};

Read the FAQ!

http://c-faq.com/decl/selfrefstruct.html


Brian
Jul 18 '06 #8

P: n/a
As long as we're on the topic of typedef, I may as well posit a
question I've been curious about for some time. Do typedefs fall into
the same precompiler realm as things like #define? It seems to me like
they ought to, since essentially they are just a more sophisticated
#define? In otherwords if you went through a program, took out all the
typedefs and manually filled them in everywhere, would it actually
change the final machine code produced?

Also tangentially related, what is the deal with the struct keyword:
it seems to me like any structure which matters, is going to be
typedefd to avoid typing "struct" every single time such an object is
declared. If I'm going to be using struct widget's extensively
throughout my code, I dont want to type "struct" a hundred million
times, im going to make the original structure a struct WIDGET and use
a typedef so everywhere i need a "struct WIDGET" I can simply type
"widget". I can hardly imagine, even in the most bizarre scenarios,
why it would actually be desirable to have to type that extra keyword
every five lines--- so why have it in the first place? It seems to
me there's no reason C shouldn't be able to detect that the user means
"struct widget *p" when they type "widget *p"...

Thanks for rocking =)
Snis Pilbor
Steve Carter wrote:
Can someone please explain why the following is not possible?
typedef foobar {
int x;
foobar *next; /* why can't we do this? */
};
Thanks
Jul 18 '06 #9

P: n/a
"Snis Pilbor" <sn********@yahoo.comwrites:
As long as we're on the topic of typedef, I may as well posit a
question I've been curious about for some time. Do typedefs fall into
the same precompiler realm as things like #define?
No.
It seems to me like they ought to, since essentially they are
just a more sophisticated #define? In otherwords if you went
through a program, took out all the typedefs and manually
filled them in everywhere, would it actually change the final
machine code produced?
A typedef is not the same as a macro, in at least two ways:

1. Typedefs are scoped. If you define an object-like
macro with a given name then it will get replaced
everywhere it occurs as a preprocessor token. But a
typedef name can be redefined as a different typedef
or a different kind of entity in an inner scope.

2. Typedefs represent a type, not a sequence of tokens.
If you declare an object like this: "mytype
foobar[20];" and mytype is "char *", the results will
differ depending on whether mytype is a macro or a
typedef.

I doubt the use or lack of use of a typedef for a type will
affect object code.
Also tangentially related, what is the deal with the struct keyword:
it seems to me like any structure which matters, is going to be
typedefd to avoid typing "struct" every single time such an object is
declared. [...]
Many C programmers prefer to write "struct <tag>" explicitly and
reserve "typedef" for situations where a type is being hidden.
--
"IMO, Perl is an excellent language to break your teeth on"
--Micah Cowan
Jul 18 '06 #10

P: n/a


Snis Pilbor wrote On 07/18/06 16:22,:
As long as we're on the topic of typedef, I may as well posit a
question I've been curious about for some time. Do typedefs fall into
the same precompiler realm as things like #define? It seems to me like
they ought to, since essentially they are just a more sophisticated
#define? In otherwords if you went through a program, took out all the
typedefs and manually filled them in everywhere, would it actually
change the final machine code produced?
No. Macro processing operates on the source code,
before types exist at all and before keywords like typedef
have any significance.

On a more concrete level, consider this fragment:

typedef double Matrix[3][3];
Matrix x;

.... and try to rewrite it using a macro

#define Matrix /* what goes here? */
Matrix x;

.... to get the same effect.
Also tangentially related, what is the deal with the struct keyword:
it seems to me like any structure which matters, is going to be
typedefd to avoid typing "struct" every single time such an object is
declared. If I'm going to be using struct widget's extensively
throughout my code, I dont want to type "struct" a hundred million
times, im going to make the original structure a struct WIDGET and use
a typedef so everywhere i need a "struct WIDGET" I can simply type
"widget". I can hardly imagine, even in the most bizarre scenarios,
why it would actually be desirable to have to type that extra keyword
every five lines--- so why have it in the first place? It seems to
me there's no reason C shouldn't be able to detect that the user means
"struct widget *p" when they type "widget *p"...
This is an unimportant matter of style -- and like most
other unimportant matters, elicits more vociferous opinions
than the things that really count! Some people feel that
writing `struct widget' is an insignificant burden, and has
the benefit of reminding the reader that the thing is in
fact a struct. If the struct-ness were hidden behind the
bland veneer of a typedef, mystifications might ensue (for a
recent example, see the "error: invalid operands to binary &"
thread).

You (and I, as it happens) are in the other camp. I find
the code reads more smoothly when a widget is just a Widget
(or a Wadget, or Boff), a single nounish word instead of a
two-word phrase in which the first word carries practically
no information I couldn't guess anyhow.

One thing I detest, though, is the use of typedef to create
aliases for pointer types. I grimace when I see

typedef struct { ... } Widget, *WidgetPtr;

In this I am inconsistent: I prefer to cover up struct-ness but
want pointer-ness to be out in the open. Pointer-ness "feels"
like a more basic quality than struct-ness; I want to know
whether I've got hold of the thing itself or just a link to it.
When I see `Widget *w' in the code I have a much better notion
of what's going on than when I see `WidgetRef w'.

I'll break my "no pointer typedefs" rule to avoid nasty-
looking situations such as commonly arise when you're casting
function pointer types back and forth, but I'll very seldom
create a typedef alias for a data pointer type.

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

Jul 18 '06 #11

P: n/a
Ben Pfaff <bl*@cs.stanford.eduwrites:
2. Typedefs represent a type, not a sequence of tokens.
If you declare an object like this: "mytype
foobar[20];" and mytype is "char *", the results will
differ depending on whether mytype is a macro or a
typedef.
This example is wrong.

(I canceled the article.)
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jul 18 '06 #12

P: n/a

Steve Carter wrote:
Roberto Waltman wrote:
Missing 'struct' - Missing new name for typedef.


Oops, I forgot to put 'struct' in (though, I meant to). I still don't
understand why you can't use the typedef name for 'next' pointer,
though.
typedef struct foobar {
int x;
foobar *next;
};
Well, you're still off; you haven't actually provided the typedef name,
which is distinct from the struct tag. The typedef for a struct looks
like this:

typedef struct optional-struct-tag { field-list } typedef-name ;

Your problem is that the typedef-name isn't defined until after the
field-list has been defined.

You can't do what you're trying to do in one pass. What you *can* do
is create an incomplete struct type, create a typedef name for it, and
then complete the struct definition with the typedef name later on:

typedef struct foo foobar;

struct foo {
int x;
foobar *next;
};

Personally I try to avoid forward-declaration issues like that; I'll
just use the struct tag to define self-referential members.

Jul 18 '06 #13

P: n/a
"Snis Pilbor" <sn********@yahoo.comwrites:
As long as we're on the topic of typedef, I may as well posit a
question I've been curious about for some time. Do typedefs fall into
the same precompiler realm as things like #define? It seems to me like
they ought to, since essentially they are just a more sophisticated
#define? In otherwords if you went through a program, took out all the
typedefs and manually filled them in everywhere, would it actually
change the final machine code produced?

Also tangentially related, what is the deal with the struct keyword:
it seems to me like any structure which matters, is going to be
typedefd to avoid typing "struct" every single time such an object is
declared. If I'm going to be using struct widget's extensively
throughout my code, I dont want to type "struct" a hundred million
times, im going to make the original structure a struct WIDGET and use
a typedef so everywhere i need a "struct WIDGET" I can simply type
"widget". I can hardly imagine, even in the most bizarre scenarios,
why it would actually be desirable to have to type that extra keyword
every five lines--- so why have it in the first place? It seems to
me there's no reason C shouldn't be able to detect that the user means
"struct widget *p" when they type "widget *p"...
Please don't top-post. See <http://www.caliburn.nl/topposting.html>.

This is, as Eric Sosman says, largely a matter of style.

Personally, I prefer to avoid typedefs for structure types. Typing
"struct foo" rather than "foo" just isn't much of a burden, and in my
opinion it makes the code clearer.

Early version of C (before K&R1) didn't have "typedef"; it was a
relatively late addition.

--
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.
Jul 18 '06 #14

P: n/a
In article <e9**********@nntp.aioe.org>, Steve Carter <st***@127.0.0.1wrote:
>Can someone please explain why the following is not possible?

typedef foobar {
int x;
foobar *next; /* why can't we do this? */
};
See <http://web.torek.net/torek/c/types2.html>. Note that only
structure tag-names "spring into being", not typedef-names.
--
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.
Jul 18 '06 #15

P: n/a
Steve Carter wrote:
>
Can someone please explain why the following is not possible?

typedef foobar {
int x;
foobar *next; /* why can't we do this? */
};
typedef struct foobar {
int x;
struct foobar *next;
} foobar;

--
pete
Jul 18 '06 #16

P: n/a

Steve Carter wrote:
Oops, I forgot to put 'struct' in (though, I meant to). I still don't
understand why you can't use the typedef name for 'next' pointer,
though.

typedef struct foobar {
int x;
foobar *next;
};
At the point of the definition of the member next, the typedef name is
unknown. The following style is fine, why not keep using it? The
keyword struct is not optional.

typedef struct foobar{
/*...*/
struct foobar *next;
};

Jul 19 '06 #17

P: n/a
Eric Sosman wrote:
No. Macro processing operates on the source code,
before types exist at all and before keywords like typedef
have any significance.

On a more concrete level, consider this fragment:

typedef double Matrix[3][3];
Matrix x;

.... and try to rewrite it using a macro

#define Matrix /* what goes here? */
Matrix x;

.... to get the same effect.
#define Matrix typedef double Mat[3][3]; Mat

You never said it needed to be able to work more than once.

--
Simon.
Jul 20 '06 #18

This discussion thread is closed

Replies have been disabled for this discussion.