Search code examples
ccompiler-errorsheader-filestypedef

typedefed struct in an header file is not identifiable in other header files that includes that file


I have a typedefed struct in an header file

data_stracture.h:

#if !defined(__DATA__STRUCTURE__HEADER__)
#define __DATA__STRUCTURE__HEADER__
#include <stdbool.h>
#include "tokenizer.h"
/*arraylist implemtation*/
#define INIT_SIZE 4
#define GROWING_FACTOR 2
typedef struct
{
    char** enumerable_items;
    int size;
    int first_free_index;
}list; 
list init_list(void);
bool add_to_end(list collection, char* added_item);
char* get_item_at_index(list access_list, int access_index);
void free_list(list memory_to_free);
list remove_item(list, char *);
/*more....*/
#endif

In a second file, in which I have included file_1.h, I have declared a method that one of it's parameters is from type list struct.

tokenizer.h:

#if !defined(__TOKENIZER__HEADER__)
#define __TOKENIZER__HEADER__
#include <stdbool.h>
#include "data_structure.h"
#define WORD_SIZE 24
typedef enum {none, asm_command, ignore, instruction}asm_line_type;

typedef struct
{
    char *label;
    char *op_name;
    struct list operands;
    bool is_instruction;
    unsigned int adress : WORD_SIZE;
    int line_number;
}asm_line_data;
#define NOT_FOUND {NULL, none, -1, false, -1}

bool match(char* command, char* match_template);
struct asm_command_syntax get_instruction_operand_amount(char *command, struct asm_command_syntax match_template);
asm_line_data *get_data(struct asm_command_syntax* command_syntax, struct list commands);
asm_line_data *tokenize(struct list string_commands, long *);
void validate_commas(struct list);
int get_word_amount(char* spaces_text);
struct asm_command_syntax classify(char* command);
#endif

Both header files have include guards.

When I am compiling the program with gcc (ansi C), I get the following compiler error:

file_2.h:22:25: error: unknown type name ‘list’
   22 | void foo(list);

I have used list in tokenizer.h many times, and the error is the same.

When I have tried to move the typedefed struct to tokenizer.h, and then included tokenizer.h in data_stracture.h, it worked fine in tokenizer.h, but than I got the same error at data_stracture.h, whenever I have used list there.

Trying to add the struct keyword doesn't work either, generating errors such as:

tokenizer.h:12:17: error: field ‘operands’ has incomplete type
   12 |     struct list operands;
      |                 ^~~~~~~~

How can I prevent such error?


Solution

  • The fundamental problem with your code as @StoryTeller-Unslander Monica stated is the circular inclusion.

    As far as I can tell you only need the struct list declaration in the tokenizer.h file.

    What you can do is to create a separate header file, let's say structure.h,declare the struct there and include it in both data_structure.h and tokenizer.h.

    structure.h

    typedef struct list{ //adding list here means you can use both list and struct list
        //...
    }list; 
    

    data_structure.h

    #include "structure.h"
    

    And remove #include "tokenizer.h" as well as the structure declaration.

    tokenizer.h

    #include "structure.h"
    

    And remove #include "data_structure.h".