单个C头文件中的循环依赖项。需要提前申报吗?

时间:2019-06-22 20:18:52

标签: c struct

#ifndef STAGE_TABLE_DEFINITION_HEADER
#define STAGE_TABLE_DEFINITION_HEADER

typedef stage_table_context_t* (*stage_table_function_t)(stage_table_context_t*);

typedef struct {
    const char* stage_name;
    stage_table_function_t* function;
} stage_t;

typedef struct {
    uint32_t error_number;
    stage_t* current_stage;
} stage_table_context_t;

#endif 

stage_table_context_t上遇到未知类型错误。

函数指针stage_table_function_t引用stage_table_context_t,而stage_table_context_t引用stage_table_function_t

显然,这里的位置无关紧要,因为任何一个方向都会导致问题。似乎我需要向前声明阶段表上下文结构,但不确定如何使用typedef进行声明。

为这个愚蠢的问题表示歉意,我离开C已有6个月了,我有点脑子屁。

edit:修复了代码中的某些错字。

2 个答案:

答案 0 :(得分:4)

您只需要告诉编译器stage_table_context_t应该是struct;这样一来,您就隐式向前声明了struct stage_table_context_t,然后可能稍后再发布其实际定义。请注意,typedef并未定义struct,而只是引入了别名。因此,实际定义为struct stage_table_context_t { ...,无论您是否为其引入别名(无论别名使用哪个名称)。

typedef struct stage_table_context_t* (*stage_table_function_t)(struct stage_table_context_t*);

typedef struct {
    const char* stage_name;
    stage_table_function_t* function;
} stage_t;

struct stage_table_context_t {
    uint32_t error_number;
    stage_t* current_stage;
};

// optional (if you want to use "stage_table_context_t" as an alias for "struct stage_table_context_t"):
typedef struct stage_table_context_t stage_table_context_t;

答案 1 :(得分:4)

您可以在struct定义之前声明它:

/* declaration */
struct foo;

.....

/* definition */
struct foo
{
   ....
};

在任何地方编写struct foo都是该结构的声明,因此您不必将其放在单独的行中,可以将其放在typedef,指针声明等中。 请注意,有时候,像在struct foo类型的变量声明中一样,您也需要定义(以计算变量大小);

/* declare struct foo ..*/   
struct foo;

/* .. or declare struct foo ..*/   
typedef struct foo foo;

/* .. or declare struct foo ..*/   
struct foo *p;   

/* .. or declare struct foo */   
int bar (struct foo *p);  

/* Not valid since we don't have definition yet */
struct foo f1;   

/* definition */
struct foo
{
   ....
};

/* Valid */
struct foo f2;   

在您的情况下,您没有给该结构起名字;您刚刚制作了typedef,它是匿名结构的别名。因此,要向前声明您的结构,您必须给它命名:

/* 
  forward declare the `struct stage_table_context_t` and give it a typedef alias
  with the same name as the structs name
*/ 
typedef struct stage_table_context_t stage_table_context_t;

typedef stage_table_context_t* (*stage_table_function_t)(stage_table_context_t*);

typedef struct {
    const char* stage_name;
    stage_table_function_t* function;
} stage_t;

struct stage_table_context_t{
    uint32_t error_number;
    stage_t* current_stage;
} stage_table_context_t;