【问题标题】:C Typedef - Incomplete TypeC Typedef - 不完整类型
【发布时间】:2012-11-18 00:58:52
【问题描述】:

所以,出乎意料的是,编译器决定当面吐槽: “现场客户的类型不完整”。

以下是相关的sn-ps代码:

customer.c

#include <stdlib.h>
#include <string.h>

#include "customer.h"

struct CustomerStruct;
typedef struct CustomerStruct
{
    char id[8];
    char name[30];
    char surname[30];
    char address[100];
} Customer ;

/* Functions that deal with this struct here */

客户.h

customer.h 的头文件

#include <stdlib.h>
#include <string.h>

#ifndef CUSTOMER_H
#define CUSTOMER_H

    typedef struct CustomerStruct Customer;

    /* Function prototypes here */

#endif

这是我的问题所在:

customer_list.c

#include <stdlib.h>
#include <string.h>

#include "customer.h"
#include "customer_list.h"

#include "..\utils\utils.h"


struct CustomerNodeStruct;
typedef struct CustomerNodeStruct
{
    Customer customer; /* Error Here*/
    struct CustomerNodeStruct *next;
}CustomerNode;



struct CustomerListStruct;
typedef struct CustomerListStruct
{
    CustomerNode *first;
    CustomerNode *last;
}CustomerList;

/* Functions that deal with the CustomerList struct here */

这个源文件有一个头文件 customer_list.h ,但我认为它不相关。

我的问题

在 customer_list.c 中,在带有注释 /* Error Here */ 的行中,编译器抱怨 field customer has incomplete type.

我整天都在谷歌上搜索这个问题,现在我要拔出我的眼球并将它们与草莓混合。

这个错误的根源是什么?

提前致谢:)

[附注如果我忘了提什么,请告诉我。正如你所言,这对我来说是压力很大的一天]

【问题讨论】:

  • 结构定义本身必须在标头中,而不仅仅是 typedef。
  • 编译器需要知道struct,因为它需要知道每个数据的大小。
  • 首先出现在我面前的是"..\utils\utils.h",但我怀疑这会导致错误。不过,tils 不是十六进制数字。
  • 让我猜猜...如果您更改包含customer.hcustomer_list.h 的顺序,一切都会开始工作。你应该在使用它之前定义你的结构!
  • 这只是我编写的源文件的标题,具有我在整个项目中使用的常用功能。删除重复代码:)

标签: c struct typedef header-files incomplete-type


【解决方案1】:

将结构声明移动到标题:

customer.h
typedef struct CustomerStruct
{
...
}

【讨论】:

  • 所以等等……我在头文件中声明了typedef和struct。但这在源文件中留下了什么?
  • @ZyykSavvins 问题是编译器不知道结构是什么样的。
  • @ZyykSavvins 通常使用结构的函数,例如print_customer(Customer *cust)。如果你不需要函数,那么你不需要定义一个 .c 文件,你可以只拥有头文件而不附带 .c 文件。
  • 谢谢!我确实有一些功能。只是现在该结构在标头中声明。再次感谢 :) 问题解决了
【解决方案2】:

在 C 语言中,编译器需要能够计算出任何直接引用的对象的大小。可以计算 sizeof(CustomerNode) 的唯一方法是在编译器构建 customer_list.c 时,编译器可以使用 Customer 的定义。

解决方案是将结构体的定义从customer.c移动到customer.h

【讨论】:

  • -.- 告诉我这很简单。谢谢!有效。所以为了清楚起见,我在我的头文件中定义和声明我的结构和 typedef,然后将头文件包含在其匹配的源文件中?
  • 您可以在任何需要您定义的结构和类型定义的 .c 或 .h 文件中包含头文件。除了结构和类型定义之外,您还可以将与功能相关的函数的任何原型放在头文件中。在匹配的 .c 文件中,您将放置函数的实现。如果没有要实现的功能,那么通常您会完全省略 .c 文件。
【解决方案3】:

您所拥有的是您尝试实例化的Customer 结构的前向声明。这实际上是不允许的,因为编译器不知道结构布局,除非它看到它的定义。所以你要做的就是把你的定义从源文件移到头文件中。

【讨论】:

    【解决方案4】:

    好像是这样的

    typedef struct foo bar;
    

    没有标题中的定义将无法工作。但是像

    typedef struct foo *baz;
    

    只要您不需要在标题中使用baz-&gt;xxx,就可以使用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      • 2011-09-10
      • 2013-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多