T
T Koster
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
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