473,385 Members | 1,338 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Circular (triangular) structure reference

After a few years of programming C, I had come to believe that I finally
knew how to correctly organise my structure definitions in header files
for mutually dependent structures, but I find myself stumped again with
this little love triangle. Here is some background:

m_commands.h defines
- struct command_callbacks, which contains
- a struct conn * reference
- struct command, which contains
- a struct command_callback reference
- a struct conn * reference
- struct input, which contains
- a struct conn * reference
- a struct command * reference
m_net.h defines
- struct conn, which contains
- a struct command * reference

The header files are guarded against circular inclusion using the the
standard #ifndef MYHEADER/#define MYHEADER/#endif wrappings.

Now both header files include each other, as "struct conn" requires a
"struct input *" element, and each "struct input" element requires a
"struct conn *" element. So far this has not caused any problems thanks
to the circular loop guards. However, this time "struct command",
through the elements in the command_callbacks structure, contains
pointers to a function which takes a "struct conn *" parameter, and this
appears to be giving problems when m_net.h is included first.

For example:
main.c includes m_net.h
....which includes m_commands.h
....which doesn't re-include m_net.h due to the #defined include-guard
to stop the circular inclusion loop
m_commands.h 'tries' to define "struct command_callbacks" which contains
some function pointers with "struct conn *" parameters, but "struct
conn" is not defined until *after* m_commands.h has been included.

For those of you who use gcc, its warnings are as follows:
In file included from m_net.h:11,
from main.c:7:
m_commands.h:31: warning: `struct conn' declared inside parameter list
In file included from m_net.h:11,
from m_net.c:21:
m_commands.h:31: warning: `struct conn' declared inside parameter list
If all that was a bit cryptic, the problem parts of the header files in
question are included below for those who would understand the problem
better from reading the C:

<-------- m_commands.h -------->
#ifndef INC_COMMANDS_H
#define INC_COMMANDS_H

#include "m_net.h"

struct command_callbacks
{
int (*execute)(struct conn *, int, void **);
int (*abort)(struct conn *);
};

struct command
{
char * name;
int argc_expect;
int * argv_expect;
int flags;
struct command_callbacks callbacks;
};

struct input
{
struct command * cmd;
struct conn * caller;
int argc;
void ** argv;
};
#endif

<-------- m_net.h -------->
#ifndef INC_NET_H
#define INC_NET_H

#include "m_db.h" /* for Queue types -- irrelevant here */
#include "m_commands.h"

struct conn
{
struct conn * prev;
struct conn * next;

int fd;
char * address;

int phase;
int security;

char input_buf[MAX_INPUT_LINE_LENGTH];
char * input_buf_cursor;

Queue * input_queue;
Queue * output_queue;

struct input * last_input;
};
#endif

I hope that's all comprehensible. How would I go about fixing this?
The FAQ answers 1.14, 2.3 and 10.7 seem inadequate for this problem.

Thanks in advance,
Thomas
Nov 14 '05 #1
6 2804
T Koster wrote:

After a few years of programming C, I had come to believe that I finally
knew how to correctly organise my structure definitions in header files
for mutually dependent structures, but I find myself stumped again with
this little love triangle. Here is some background:

m_commands.h defines
- struct command_callbacks, which contains
- a struct conn * reference
- struct command, which contains
- a struct command_callback reference
- a struct conn * reference
- struct input, which contains
- a struct conn * reference
- a struct command * reference


Add m_commands_meta.h:

#ifdef etc
struct command_callbacks;
struct command;
struct input;
#endif

Include this instead of m_commands.h, in your other headers.
etc etc ad nauseam
Nov 14 '05 #2
infobahn wrote:
T Koster wrote:
After a few years of programming C, I had come to believe that I finally
knew how to correctly organise my structure definitions in header files
for mutually dependent structures, but I find myself stumped again with
this little love triangle. Here is some background:

m_commands.h defines
- struct command_callbacks, which contains
- a struct conn * reference
- struct command, which contains
- a struct command_callback reference
- a struct conn * reference
- struct input, which contains
- a struct conn * reference
- a struct command * reference


Add m_commands_meta.h:

#ifdef etc
struct command_callbacks;
struct command;
struct input;
#endif

Include this instead of m_commands.h, in your other headers.
etc etc ad nauseam


Thanks, that fixed it. I'll make such "_meta.h" header files for all
those like interfaces, and include those instead when only a bare-bones
structure tag declaration is required to satisfy the language, rather
than full knowledge of the structure definition.

Thomas
Nov 14 '05 #3
infobahn <in******@btinternet.com> writes:
Add m_commands_meta.h:

#ifdef etc
struct command_callbacks;
struct command;
struct input;
#endif

Include this instead of m_commands.h, in your other headers.


It seems silly to me to add an entire header file for this, when
it is perfectly safe to write `struct command;', etc., in any
header file that needs it.
--
Ben Pfaff
email: bl*@cs.stanford.edu
web: http://benpfaff.org
Nov 14 '05 #4
Ben Pfaff wrote:

infobahn <in******@btinternet.com> writes:
Add m_commands_meta.h:

#ifdef etc
struct command_callbacks;
struct command;
struct input;
#endif

Include this instead of m_commands.h, in your other headers.


It seems silly to me to add an entire header file for this, when
it is perfectly safe to write `struct command;', etc., in any
header file that needs it.


Depends on how volatile the names are.
Nov 14 '05 #5
infobahn <in******@btinternet.com> writes:
Ben Pfaff wrote:

infobahn <in******@btinternet.com> writes:
> Add m_commands_meta.h:
>
> #ifdef etc
> struct command_callbacks;
> struct command;
> struct input;
> #endif
>
> Include this instead of m_commands.h, in your other headers.


It seems silly to me to add an entire header file for this, when
it is perfectly safe to write `struct command;', etc., in any
header file that needs it.


Depends on how volatile the names are.


If you change the names, you will have to change the references
to them. As far as I can tell that's normally enough work that
an extra header won't help significantly.
--
"Some people *are* arrogant, and others read the FAQ."
--Chris Dollin
Nov 14 '05 #6
Ben Pfaff wrote:

infobahn <in******@btinternet.com> writes:
Ben Pfaff wrote:

infobahn <in******@btinternet.com> writes:

> Add m_commands_meta.h:
>
> #ifdef etc
> struct command_callbacks;
> struct command;
> struct input;
> #endif
>
> Include this instead of m_commands.h, in your other headers.

It seems silly to me to add an entire header file for this, when
it is perfectly safe to write `struct command;', etc., in any
header file that needs it.


Depends on how volatile the names are.


If you change the names, you will have to change the references
to them.


Yeah, I was thinking the same thing just after I pressed that button.
Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: Kiuhnm | last post by:
Is there an elegant way to deal with semi-circular definitions? Semi-circular definition: A { B }; B { *A }; Circular reference: A { *B }; B { *A }; The problems arise when there are more...
1
by: dotnetnewbie | last post by:
Hi all I am new to .NET and webservice so I wish someone can shed some light on me. I have a Project class and a Product class, the Project can contain multiple Products (as an ArrayList). In...
11
by: Steve Jorgensen | last post by:
I just came up with a really tidy little solution to the VB/VBA circular reference issue. It only works with Access 2000 or newer, but that's about the only down-side. The issue... You need an...
3
by: JCB | last post by:
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...
2
by: Bob Jenkins | last post by:
I have this cute data structure that I just found a second opportunity to use. I googled for references to it, but came up empty. I probably just don't know its name. The algorithm on this...
1
by: Guogang | last post by:
Hi, I have a tree structure in C# with pointer to children and parent. This will form a circular reference. My question: will this kind of circular reference affect garbage collection (parent...
2
by: Rimma Meital via .NET 247 | last post by:
(Type your message here) -------------------------------- From: Rimma Meital I have 2 DLLs (Class Libraries). Both defines single-ton objects - logger object (writes to logger) and...
10
by: Nevets Steprock | last post by:
I'm writing a web program where one of the sections is supposed to output a correlation matrix. The typical correlation matrix looks like this: ..23 ..34 .54 ..76 .44 .28 ..02 .77 ...
6
by: Karthik V | last post by:
I've been facing this situation often: class NewFeature { TheClass *theClass; NewFeature(TheClass *t) { theClass = t; } void act() { // call methods on theClass } }
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.