C中简单的头文件可见性混淆



我在C语言中有一个关于包含头文件的奇怪问题。

c

#include <stdio.h>
#include <stdlib.h>
#include "location.h"
int waste_new_line();
int main()
{
    location *crossroads = malloc(sizeof(*crossroads));
...

location.h

typedef struct Location_Struct location;

location.c

typedef struct Location_Struct {
    int ID;
    char *name;
    char *description;
} location;
int setup_location(location* l, char* name)
{
    ...

现在不起作用了,因为

location *crossroads = malloc(sizeof(*crossroads));

抛出一个指向不完整类型的解引用指针错误,这意味着它可以看到location.h的内容,但它似乎不知道location.c…

我看了一下,我看到的所有教程都说链接器会把两个文件链接在一起。

编辑:

我修改了代码,在location.c中包含一个初始化器,如下所示:

c

...
#include "location.h"
int waste_new_line();
int main()
{
    location *crossroads = initialize_location();
    ....

location.h

typedef struct Location_Struct location;
location* initialize_location();

location.c

...
typedef struct Location_Struct {
    int ID;
    char *name;
    char *description;
} location;
location* initialize_location(location* l)
{
    return malloc(sizeof(location));
}
...

这仍然抛出相同的错误,但只有当我尝试使用:

访问crossroads的成员时才会抛出相同的错误:
crossroads->description

这会抛出不完整类型错误。

编辑2:现在我决定只是把结构体定义在头文件…

这种行为是预期的。当您使用#include "location.h"时,只有头文件对编译器可见。location.c文件稍后在链接时出现。

你有两个选择:

  1. 添加一个函数,在location.h中声明并在location.c中定义,它执行必要的malloc并返回一个指针。
  2. 将结构体的完整定义移动到头文件中。

main文件知道一个名为Location_Structstruct(和一个typedef)。它不知道它有多大,因此你不能对它应用sizeof

既然你有效地隐藏了布局和Location_Struct的实现,那么提供一个"构造器"是有意义的。

编辑

似乎我必须提到"构造器"我的意思是一个普通的函数,它可以访问结构的实现,可以分配和可能的预填充对象。

您需要将Location_Struct的定义放在头文件location.h中。编译器不会"看到"另一个源文件(除非它是#include,这通常不是一个好主意)。

最新更新