c语言 - 当两个文件相互包含时,为什么我不能有一个内部结构?



作为上下文,我正在编写一个操作系统:

我有一个struct vt_device_s和一个struct __vt_device_s,它们是特定于建筑的,位于vt_device_s内部,像这样:

struct
vt_device_s
{
struct __vt_device_s __device;
size_t cursor_x;
size_t cursor_y;
};

现在对于架构结构:

struct
__vt_device_s
{
uint16_t *memory;
size_t memory_len;
};

<dev/vt.h>知道__vt_device_s定义在<sys/_vt.h>,因为它被包括在内,但我得到这个错误:

error: field '__device' has incomplete type
48 |  struct __vt_device_s __device;
|

我意识到这是因为两个文件相互依赖(整个冲突是由_vt.c引起的,包括_vt.h,包括vt.h,包括_vt.h),但我不明白这是一个编译问题。我在两个文件里都有警卫!

PS:我理解这将是一个没有问题,如果我使用一个指针,但因为它是一个操作系统,这个驱动程序需要在分页设置之前运行(也就是说,mallocfree还不存在)。

下面是有问题的三个文件:

dev/vt.h

#ifndef _DEV_VT_H_
#define _DEV_VT_H_ 1
#include <stddef.h>
#include <sys/_vt.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct
vt_device_s
{
struct __vt_device_s __device;
size_t cursor_x;
size_t cursor_y;
};
void vt_init(struct vt_device_s *);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _DEV_VT_H_ */

sys/_vt.h

#ifndef _I386__VT_H_
#define _I386__VT_H_ 1
#include <stddef.h>
#include <stdint.h>
#include <dev/vt.h>
#define __VT_WIDTH  80
#define __VT_HEIGHT 25
#define __VT_MEMOFF 0xb8000
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
struct
__vt_device_s
{
uint16_t *memory;
size_t memory_len;
};
void __vt_init(struct vt_device_s *);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _I386__VT_H_ */

sys/_vt.c

#include <sys/_vt.h>
void
__vt_init(struct vt_device_s *device)
{
device->__device.memory = (uint16_t *) __VT_MEMOFF;
device->__device.memory_len = __VT_WIDTH * __VT_HEIGHT;
}

您的双包含保护可以防止一个文件在被另一个文件重新包含时包含自己。解决这个问题的唯一方法就是你必须打破这个循环。决定哪个标题"更高";并将包括" lower "不要试图把高的和低的包含在一起。

这样做的原因是预处理器必须将多个文件转换为编译器的一个线性序列。编译器必须先看到一组文件内容,再看到另一组文件内容。

如果你有像这样的循环包含,你让代码的最终用户决定哪一个先出现。如果它们包含文件A,那么它将包含文件B,文件B将尝试再次包含文件A,但它将被包含保护阻止,因此B的内容将首先被解析。另一方面,如果最终用户首先包含B,则编译器将首先看到A的内容。

所以如果你让它保持原样,那么它实际上是随机的哪个文件首先被包含。如果你打破了这个循环,你可以自己决定先包含哪个。

一旦你决定了,你可以修复编译器关于不完整类型的错误,使你选择的第一个文件能够独立存在,然后让第二个文件使用第一个文件的定义。

最新更新