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

A dilemna with circular reference of headers file

P: n/a
JCB
Hi,

I have two C file which are referencing in a circular way.

To simplify I use an example with car :

Suppose I have a program for cars.

I have car.c, structure car and functions prototypes of car.c are in a
file car.h
I have also engine.c, a structure engine and functions prototypes of
engin.c are in a file engine.h.
Now the structure car in car.c use an engine structure, so I have to
write in car.c :

#include car.h
#include engine.h

.... (code)

Note :in car.h
struct car {
struct engine engine ;
etc...
} ;

Up to there, it's standard and there is no problem.
The problem is if I have to write a function in engine.c which
reference a car, in this case, I will have to write in engine.c :

#include engine.h
#include car.h

The problem is that engine depends on car and car depends on engine,
so either I write
(case 1)
#include engine.h
#include car.h
or
(case 2)
#include car.h
#include engine.h

it's not appropriated :

case 1
Function of car.h use the structure engine.h, so it's good, but
engine.h use structure car in car.h, not yet defined (because #include
car.h is after #include engine.h)
case 2:
Functions of engine.h that use structure car it's good, because
defined before, but in car.h , I need a reference to struct engine,
not yet defined...

Some people kwow what to do in this particular case ?
Nov 13 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a

On Tue, 8 Jul 2003, Pieter Droogendijk wrote:

On 8 Jul 2003 08:09:05 -0700, JCB wrote:

I have two C file which are referencing in a circular way. Some people kwow what to do in this particular case ?


car.h:
#ifndef __INCLUDED_CAR_H__
#define __INCLUDED_CAR_H__


Constraint violation. I used to be lax about this
case myself, until repeated admonitions in c.l.c gradually
changed my style. Now, I write instead:

#ifndef H_CAR
#define H_CAR

Shorter to type, and portable to all ISO C compilers.
Everyone wins.

Also N.B.: I have found that some circular references are
not fully defused until one has put all type declarations
above the other headers. I forget in what circumstances this
bit me, but now I also write:

engine.h:
#ifndef H_ENGINE
#define H_ENGINE

typedef struct engine Engine;

#include "car.h"

struct engine
{
Car *my_owner;
};

#endif

car.h:
#ifndef H_CAR
#define H_CAR

typedef struct car Car;

#include "engine.h"

struct car
{
Engine *my_engine;
};

#endif
-Arthur

Nov 13 '05 #2

P: n/a
In 'comp.lang.c', Pieter Droogendijk <gi*@binky.homeunix.org> wrote:
#ifndef __INCLUDED_CAR_H__
#define __INCLUDED_CAR_H__


Please stop invading the implementation name space (_[A-Z_]xx identifiers
are reserved). The idiomatic form is:

#ifndef H_INCLUDED_CAR
#define H_INCLUDED_CAR

--
-ed- em**********@noos.fr [remove YOURBRA before answering me]
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
<blank line>
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 13 '05 #3

P: n/a

On Tue, 8 Jul 2003, Derk Gwen wrote:

[stupid octothorpe quoting fixed]
jc*********@netcourrier.com (JCB) wrote:

I have two C file which are referencing in a circular way.

I have car.c, structure car and functions prototypes of car.c are in a
file car.h
I have also engine.c, a structure engine and functions prototypes of
engin.c are in a file engine.h.
If car and engine are so incestuous that they need to know each other's
structures, you should move them into one file. They are tightly coupled
and the program organisation should reflect that.


IMHO, not if the concept of "engine" is distinct from the concept of "car"
(which in this trivial example it is). A car "has-a" engine, but so do
other things, and maybe someday you'll want to change your "engine" class
to work with "lawnmowers", without having to weed out all the intermixed
declarations and definitions of "car"-related methods.

Of course, any beginner's textbook would tell you to use inheritance from
an "Engine-Powered Vehicle" class in the first place. But I don't listen
to that kind of textbook. ;-)

My advice: Keep the separate files. Just put them in the same directory.
IMHO.
You can couple them more loosely by using pointers to incomplete
structures and functions.
car.h
#ifndef car_h
#define car_h
#include "engine.h"
typedef struct car car;
t functionname(engine *...);
t functionname(...);
...
#endif
Ahh. *This* is where the problem I mentioned earlier bites people.
Look at what happens when this file is preprocessed:
#ifndef car_h
#define car_h
#include "engine.h" "car_h" is not defined, so "car_h" gets defined.
Then we #include "engine.h" as follows: #ifndef engine_h
#define engine_h
#include "car.h" "engine_h" is not defined, so "engine_h" gets defined.
Then we #include "car.h" as follows: #ifndef car_h "car_h" is defined, so we skip to the corresponding #endif ....and return to processing "engine.h".
typedef struct engine engine;
Now we have a typedef for "engine". Good.
t functionname(car *...);


Now we have a function taking a "car *". Bad.
The identifier "car" has not been declared to mean
anything anywhere. The compiler chokes.

The solution to this problem is left as an exercise
for Derk. (I explained it, albeit less lucidly, earlier
in the thread.)

-Arthur

Nov 13 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.