typedef, structs, and pointers

S

Steve Carter

Can someone please explain why the following is not possible?


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


Thanks
 
R

Roberto Waltman

Steve Carter said:
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.
 
S

Steve Carter

Roberto said:
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;
};
 
B

Ben Pfaff

Steve Carter said:
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.
 
W

Walter Roberson

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

Eric Sosman

Steve Carter wrote On 07/18/06 15:10,:
Roberto Waltman 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;
};

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

Roberto Waltman

Steve Carter said:
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;
 
S

Snis Pilbor

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
 
B

Ben Pfaff

Snis Pilbor said:
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.
 
B

Ben Pfaff

Ben Pfaff said:
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.)
 
E

Eric Sosman

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

John Bode

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

Keith Thompson

Snis Pilbor said:
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.
 
P

pete

Steve said:
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;
 
L

lovecreatesbeauty

Steve said:
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;
};
 
S

Simon Biber

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

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top