Reputation: 833
I have 3 files:
-file 1 has table1 struct and a function that acts on table 2 structs
// header file table 1
#include "table_2.h"
typedef struct{...}table1;
void * doSomethingGivenTable2(table2 * t2);
-file 2 has table2 struct and a function that acts on table 1 structs
// header file table 2
#include "table_1.h"
typedef struct{...}table2;
void * doSomethingGivenTable1(table1 * t1);
-file 3 uses both of the structs from file 1 and 2
#include "table_1.h"
#include "table_2.h"
// this is fine because I am including both of them in a separate file
What happens in file 3 is fine, but file 1 and file 2 produce error: unknown type name
for the structs since I am including the header of each file in the other file. I am also defining functions that use the other's structs. Can I fix this while leaving both of the functions in their places? If not, then what alternatives do I have?
Thanks
Upvotes: 1
Views: 2315
Reputation: 24905
You need to use forward declaration.
In your file 1, add the following statement:
typedef struct tbl2 table2;
In your file 2, add the following statement:
typedef struct tbl1 table1;
In your file 3, add the following statements:
typedef struct tbl1 table1;
typedef struct tbl2 table2;
This is known as forward declaration, which tells your compiler that these structures are available elsewhere and not to complain.
Upvotes: 1
Reputation: 17503
You need structure tags so you can typedef
an identifier for an incomplete structure type. To avoid defining the same typedef
identifier multiple times, the typedef
declarations can be moved into a common header file as follows:
table_common.h:
#ifndef TABLE_COMMON_H_INCLUDED
#define TABLE_COMMON_H_INCLUDED
typedef struct table1 table1;
typedef struct table2 table2;
#endif
table_1.h:
#ifndef TABLE_1_H_INCLUDED
#define TABLE_1_H_INCLUDED
#include "table_common.h"
struct table1 {
...
};
void * doSomethingGivenTable2(table2 * t2);
#endif
table_2.h:
#ifndef TABLE_2_H_INCLUDED
#define TABLE_2_H_INCLUDED
#include "table_common.h"
struct table2 {
...
};
void * doSomethingGivenTable1(table1 * t1);
#endif
Notes:
The table1
in struct table1
is a structure tag. I used the same name for the structure tag and its associated typedef
identifier. The same name can be used because the namespace for structure tags is different to the namespace for other identifiers. However, there is no requirement for the structure tag name to match the typedef identifier so you can make them different if you want.
The header files I wrote use a common preprocessor trick to avoid problems when the same header file is included more than once. The macros defined for this trick are known as "guard macros".
Upvotes: 4
Reputation: 8142
You can separate the typedef
from the actual struct
definition like this. This allows the compiler to know that table1
is a datatype it can expect to find, but that it will get the full definition of it later, so not to worry that it doesn't know what it actually is yet.
#ifndef TABLE1_H
#define TABLE1_H
typedef struct table1_s table1;
#include "table2.h"
struct table1_s
{
// contents of struct
};
#endif
As an aside, if you have functions that only make use of (for example) table2
, they should be declared in the same include file as table2
, not table1
.
Upvotes: 2
Reputation: 378
Declare the struct name in the header of the opposite table as well, like
typedef struct table1 table1;
inside table2.h and vice versa.
Upvotes: 1