include-guard不允许我声明类型



我遇到了这样一个有趣的问题,因为include-guard触发器,头文件中声明的类型没有声明。我有一个互斥文件.h,它描述了互斥类型,它取决于线程文件.h中声明的线程类型,然而,线程依赖于互斥,主.c文件同时使用这两种类型。

问题:编译main.c时,线程文件是include.h,其中包括mutex.h,但是,由于thread.h已经连接,因此它推出了include-guard,并且不允许在mutex.h 中声明thread_t类型

thread.h

#ifndef _THREAD_H_
#define _THREAD_H_
#include "mutex.h"
typedef struct thread
{
int thread_data;
} thread_t;
extern mutex_t* get_mutex();
#endif

互斥锁.h

#ifndef _MUTEX_H_
#define _MUTEX_H_
#include "thread.h"
#include "stdint.h"
typedef struct mutex {
uint8_t      lock_status; //+0
thread_t*    waiting_thread_queue[1024];
} mutex_t;
extern thread_t* get_thread();
#endif

main.c

#include "stdlib.h"
#include "stddef.h"
#include "thread.h"
int main(void) {
get_thread();
get_mutex();
return 0;
}

这是我得到的错误:

emilia@emilia-pc:~/test$ gcc main.c
In file included from thread.h:4,
from main.c:3:
mutex.h:9:5: error: unknown type name ‘thread_t’
9 |     thread_t*    waiting_thread_queue[1024];
      |     ^~~~~~~~
mutex.h:12:8: error: unknown type name ‘thread_t’
12 | extern thread_t* get_thread();
      |        ^~~~~~~~

两个标头之间存在循环依赖关系。线程头需要互斥,反之亦然

你做这件事的方式没有道理。线程头声明了一个名为get_mutex的函数,反之亦然,互斥体头声明了名为get_thread的函数。

这可能意味着,标头之间的关系非常密切,它们应该是一个标头。

无论如何,我们打破循环依赖关系的方法是在其中一个标头中使用前向声明。

// child.h
struct parent; // incomplete "forward" declaration
struct child {
struct parent *parent;
};
// parent.h
#include "child.h"
#define MAX_CHILDREN 42
struct parent {
struct child *children[MAX_CHILDREN];
};

";向前";声明struct parent不需要parent.h标头。parent.h标头获取该声明,但它不会干扰自己的声明,因为这是允许的:

struct parent;
struct parent { ... };

请注意,_THREAD_H_侵入了一个保留的实现命名空间。保留以下划线开头、后跟大写字母或其他下划线的名称。违反这条规则实际上是未定义的行为,可能会产生任何后果。实现可能会停止使用诊断消息翻译程序。或者,它可以预定义一个名为_THREAD_H_的宏,这样您自己的标头就无法生成预期的内容。

最新更新