Ahmed Al-haddad
Ahmed Al-haddad

Reputation: 833

C struct - error: unknown type name between two files

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

Answers (4)

Jay
Jay

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

Ian Abbott
Ian Abbott

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:

  1. 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.

  2. 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

Chris Turner
Chris Turner

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

Hongyu Wang
Hongyu Wang

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

Related Questions