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

struct and typedef problems

P: n/a
Hello,
i am writing a program under linux in c and compile my code with make
and gcc.

Now i have 4 files: init.c/h and packets.c/h. Each header-file contains
some:

init.h:
struct xyz
{
int a;
};
typedef struct xyz XYZ;

void fkt_1(XYZ *, ABC *);

packets.h:
struct abc
{
int b;
}
typedef struct abc ABC;

void fkt_2(XYZ *, ABC *);

Because one file is compiling before the other this one does not know
the structure from the other and i get an parser error before, let's
say, ABC.

I did some research in this newsgroup and in the internet, tried to use
"extern struct abc" or something like that but nothing worked.

Can anybody tell me what is wrong and how to fix it?

Many thanks

björn

Nov 14 '05 #1
Share this Question
Share on Google+
16 Replies


P: n/a
burn wrote:

Hello,
i am writing a program under linux in c and compile my code with make
and gcc.

Now i have 4 files: init.c/h and packets.c/h. Each header-file contains
some:

init.h:
struct xyz
{
int a;
};
typedef struct xyz XYZ;

void fkt_1(XYZ *, ABC *);

packets.h:
struct abc
{
int b;
}
typedef struct abc ABC;

void fkt_2(XYZ *, ABC *);

Because one file is compiling before the other this one does not know
the structure from the other and i get an parser error before, let's
say, ABC.

I did some research in this newsgroup and in the internet, tried to use
"extern struct abc" or something like that but nothing worked.

Can anybody tell me what is wrong and how to fix it?


This will work,
if the macros haven't already been defined for something else:

/* BEGIN init.h */

#ifndef H_INIT
#define H_INIT

#include "packets.h"

struct xyz {
int a;
};

typedef struct xyz XYZ;

void fkt_1(XYZ *, ABC *);

#endif

/* END init.h */
/* BEGIN packets.h */

#ifndef H_PACKETS
#define H_PACKETS

#include "init.h"

struct abc {
int b;
};

typedef struct abc ABC;

void fkt_2(XYZ *, ABC *);

void fkt_1(XYZ *, ABC *);

#endif

/* END packets.h */

There's a good chance that these two files might be better off
combined as one.
--
pete
Nov 14 '05 #2

P: n/a
Unfortunately - the entire thing is an indicator of bad planning.

If the two modules are sharing a common interface - then it's best to
have them share a common header file to that interface and types used
within that interface.

Nov 14 '05 #3

P: n/a
thank you for the prompt reply. you both are right, i should probably
restructure my code.

the problem is that i have multiple files doing multiple things on the
same kind of structures - but i think a little bit of thinking should
get that straight ;-)

Nov 14 '05 #4

P: n/a
"burn" <bj**************@web.de> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
thank you for the prompt reply. you both are right, i should probably
restructure my code.

the problem is that i have multiple files doing multiple things on the
same kind of structures - but i think a little bit of thinking should
get that straight ;-)


A common solution is to put all type definitions in types.h and have all
..c files #include "types.h".

<OT>
If you're using a Makefile, be sure to add types.h as a dependency for
all the files that #include it, or your files won't be rebuilt properly
when you make changes to it.
</OT>

S

--
Stephen Sprunk "Those people who think they know everything
CCIE #3723 are a great annoyance to those of us who do."
K5SSS --Isaac Asimov
Nov 14 '05 #5

P: n/a


cl****@anodized.com wrote:
Unfortunately - the entire thing is an indicator of bad planning.

Please quote a relevant portion of the previous message when replying.
To do so from the Google interface, don't use the Reply at the bottom
of the message. Instead, click "show options" and use the Reply shown
in the expanded headers.

Brian

Nov 14 '05 #6

P: n/a


burn wrote:
thank you for the prompt reply. you both are right, i should probably
restructure my code.

Please quote a relevant portion of the previous message when replying.
To do so from the Google interface, don't use the Reply at the bottom
of the message. Instead, click "show options" and use the Reply shown
in the expanded headers.

Brian

Nov 14 '05 #7

P: n/a
burn wrote:

Now i have 4 files: init.c/h and packets.c/h. Each header-file
contains some:
*** edited for minimum vertical space ***
init.h:
struct xyz { int a; };
typedef struct xyz XYZ;
void fkt_1(XYZ *, ABC *);

packets.h:
struct abc { int b; }
typedef struct abc ABC;
void fkt_2(XYZ *, ABC *);

Because one file is compiling before the other this one does
not know the structure from the other and i get an parser error
before, let's say, ABC.

I did some research in this newsgroup and in the internet,
tried to use "extern struct abc" or something like that but
nothing worked.

Can anybody tell me what is wrong and how to fix it?


Forget about .h files for now and concentrate on the needs of the
..c files. First, what is in each .c file that the other .c file
needs to know? That is what goes in the .h file. Its purpose is
to export facts to whatever needs to know about them.

Now you can also use a partial definition of a structure pointer,
until such time as it has to be dereferenced. You can do this
because all pointers to structs occupy the same space and have the
same alignment requirements. Possibly the easiest way is:

/* init.h */
#ifndef H_init_h
#define H_init_h
#include "packets.h"
.... stuff ...
#endif

and the same for packets.h with the init<-->packet ids
interchanged. Then each .c file only has to #include one .h file.
There are negatives to this.

The point to remember is that .h files export things, and they
never define data nor functions, although they may declare them.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #8

P: n/a
Hi,

I think there is no need to combine these two files.
There is a keyword "extern" in C language which tells the compiler that
those functions or variables which are declared with extern are defined
in another file .

So u have to include the other file into this file and declare the
structure in the other file with extern keyword.

I hope this will be of great help for u.

http://publications.gbdirect.co.uk/c...4/linkage.html

Sarath.B
IIIT-H
India.

Nov 14 '05 #9

P: n/a
"Sarath" <bs******@gmail.com> writes:
I think there is no need to combine these two files.
There is a keyword "extern" in C language which tells the compiler that
those functions or variables which are declared with extern are defined
in another file .

So u have to include the other file into this file and declare the
structure in the other file with extern keyword.

I hope this will be of great help for u.

http://publications.gbdirect.co.uk/c...4/linkage.html


Sarath, I have a couple of requests (things that you should already
have run across if you've been following this newsgroup).

Please provide some context when posting a followup. It's difficult
to tell what "these to files" refers to. It's seldom necessary to
quote the entire article, just enough to make it possible to
understand the followup without seeing the parent article (which may
not be easily available).

To quote CBFalconer's sig quote (in which he quotes me):

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

Second, please don't use abbreviations like "u" for "you", "ur" for
"your", and "r" for "are". I'm sure they're perfectly legible if
you're accustomed to them, but most of us aren't. (I understand
they're particularly difficult for many people whose first language is
not English.)

Thanks.

--
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 #10

P: n/a
On Fri, 10 Jun 2005 22:28:55 -0700, Sarath wrote:
Hi,

I think there is no need to combine these two files.
There is a keyword "extern" in C language which tells the compiler that
those functions or variables which are declared with extern are defined
in another file .
The OP mentioned that he trued extern. However that's not appropriate here
since the problem involves types, not objects or functions, and types have
no linkage. So what happens in one file has no bearing
on what happens in anothger, separately compiled file. That's a key
purpose of headers, having the same definitions available in separately
compiled parts of the program.
So u have to include the other file into this file and declare the
structure in the other file with extern keyword.


The extern keyword is not applicable to type declarations, just functions
and objects.

Lawrence
Nov 14 '05 #11

P: n/a
Keith Thompson wrote:
.... snip ...
Second, please don't use abbreviations like "u" for "you", "ur"
for "your", and "r" for "are". I'm sure they're perfectly
legible if you're accustomed to them, but most of us aren't.
(I understand they're particularly difficult for many people
whose first language is not English.)


And particularly annoying to those whose first language is
English. To a non-English speaker, whose doesn't have the clue of
pronounciation and to whom English is a written only language,
those abbreviations are totally useless.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #12

P: n/a


Keith Thompson wrote:
"Sarath" <bs******@gmail.com> writes:
I think there is no need to combine these two files.
There is a keyword "extern" in C language which tells the compiler that
those functions or variables which are declared with extern are defined
in another file .

So u have to include the other file into this file and declare the
structure in the other file with extern keyword.

I hope this will be of great help for u.

http://publications.gbdirect.co.uk/c...4/linkage.html
Sarath, I have a couple of requests (things that you should already
have run across if you've been following this newsgroup).

Please provide some context when posting a followup. It's difficult
to tell what "these to files" refers to. It's seldom necessary to
quote the entire article, just enough to make it possible to
understand the followup without seeing the parent article (which may
not be easily available).

To quote CBFalconer's sig quote (in which he quotes me):

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

Second, please don't use abbreviations like "u" for "you", "ur" for
"your", and "r" for "are". I'm sure they're perfectly legible if
you're accustomed to them, but most of us aren't. (I understand
they're particularly difficult for many people whose first language is
not English.)

Thanks.

Thanks a lot for your suggestions.
Sarath.B
IIIT-H
--
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 #13

P: n/a


Keith Thompson wrote:
"Sarath" <bs******@gmail.com> writes:
I think there is no need to combine these two files.
There is a keyword "extern" in C language which tells the compiler that
those functions or variables which are declared with extern are defined
in another file .

So u have to include the other file into this file and declare the
structure in the other file with extern keyword.

I hope this will be of great help for u.

http://publications.gbdirect.co.uk/c...4/linkage.html
Sarath, I have a couple of requests (things that you should already
have run across if you've been following this newsgroup).

Please provide some context when posting a followup. It's difficult
to tell what "these to files" refers to. It's seldom necessary to
quote the entire article, just enough to make it possible to
understand the followup without seeing the parent article (which may
not be easily available).

To quote CBFalconer's sig quote (in which he quotes me):

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

Second, please don't use abbreviations like "u" for "you", "ur" for
"your", and "r" for "are". I'm sure they're perfectly legible if
you're accustomed to them, but most of us aren't. (I understand
they're particularly difficult for many people whose first language is
not English.)

Thanks.

Thanks a lot for your suggestions.
Sarath.B
IIIT-H
--
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 #14

P: n/a
"Sarath" <bs******@gmail.com> writes:
Keith Thompson wrote:

[snip]
Thanks.

Thanks a lot for your suggestions.


You're welcome. And as long as you're open to suggestions:

Your most recent followup was posted twice, about 2 or 3 minutes
apart.

Your original text should generally be left-justified, not indented.

--
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 #15

P: n/a
On Fri, 10 Jun 2005 15:56:05 GMT, pete <pf*****@mindspring.com> wrote:
burn wrote:

init.h:
struct xyz <snip body>
typedef struct xyz XYZ;

void fkt_1(XYZ *, ABC *);

packets.h:
struct abc <snip body>
typedef struct abc ABC;

void fkt_2(XYZ *, ABC *);

Because one file is compiling before the other this one does not know
the structure from the other and i get an parser error before, let's
say, ABC.

I did some research in this newsgroup and in the internet, tried to use
"extern struct abc" or something like that but nothing worked.

Can anybody tell me what is wrong and how to fix it?


This will work,
if the macros haven't already been defined for something else:

<snip same plus header guards and cross-#include's,
and declaration of fkt_2 duplicated in packets.h>

Header guards solve the problem of multiple (typically implicit)
inclusion; they do nothing for inter-type dependency.

Aside from combining into a single .h, which depending on your design
may be preferable or at least conveniently acceptable, what you can do
is add a 'forward' declaration of the tag. Three ways:

In each depending file, just the tag:
----- init.h
/* add guards preferably, cross-include if you want to relieve user */
struct xyz { body }; typedef struct xyz XYZ;
/* or combine these as typedef struct xyz { body } XYZ; */
struct abc; /* tag only */ /* must be before any use in prototype */
void fkt_1 (XYZ *, struct abc *);
/* or (struct xyz *, struct abc *) to be consistent */
----- packet.h
/* ditto */
struct abc { body }; typedef struct abc ABC; /* ditto */
struct xyz; /* ditto */
void fkt_2 (struct xyz *, ABC *);
/* or (struct xyz *, struct abc *) to be consistent */

In each depending file also the typedef, but you must guard these
individually or at least separately, because you can have a or even
multiple forward declarations of a tag in addition to the full
declaration, but you cannot redeclare a typedef in C; in C++ you can
as long as the redefinition is effectively identical:
----- init.h
/* guard and cross-include similarly */
typedef struct xyz { body } XYZ; /* as above */
#ifndef T_ABC /* guard for typedef(s) */
#define T_ABC
typedef struct abc ABC;
#endif
void fkt_1 (ABC *, XYZ *);
----- packet.h
/* ditto */
typedef struct abc { body } ABC; /* ditto */
#ifndef T_XYZ /* ditto */
#define T_XYZ
typedef struct xyz XYZ;
#endif
void fkt_2 (XYZ *, ABC *);

Move the typedefs or tags only to a separate file, a la C++ <iosfwd>:
----- typenames.h
typedef struct xyz XYZ;
typedef struct abc ABC;
----- init.h
#include "typenames.h"
struct xyz { body }; /* only, no typedef */
void fkt_1 (ABC *, XYZ *);
----- packet.h
#include "typenames.h"
struct abc { body }; /* ditto */
void fkt_2 (XYZ *, ABC *);

BTW, you can use the same identifier for the struct tag and the
typedef name if you want; you don't need to use lowercase and
uppercase or similar schemes. And except for M$ -- admittedly a big
exception -- it isn't common in C to use all-caps for typedef names.
But these are only(?) style issues.

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

P: n/a
Me
> Because one file is compiling before the other this one does not know
the structure from the other and i get an parser error before, let's
say, ABC.

I did some research in this newsgroup and in the internet, tried to use
"extern struct abc" or something like that but nothing worked.
extern is about external definitions.
Can anybody tell me what is wrong and how to fix it?


You were looking for something called "forward declaration":

typedef struct foo {
int a;
} foo;

void fn(foo *, boo *);

What you should do here is somewhere above the fn function, declare an
incomplete boo struct like:

struct boo;
typedef struct boo boo;
// typedef here is optional, but very convenient

or simply just:

typedef struct boo boo;

And it will work. The bad thing about C is that it doesn't allow
duplicate typedefs like C++ does, so you will need an inclusion
mechanism of some sort for typedefs here. The other posters have a
point about just putting everything in a common header file because if
you include foo.h, you should expect that it includes everything you
need to have it work instead of also forcing the programmer to include
boo.h as well. But the forward declaration trick is very useful for
information hiding and reducing compile times (among other things), so
you should keep it in your toolbox.

Nov 14 '05 #17

This discussion thread is closed

Replies have been disabled for this discussion.