【问题标题】:How to deal with incomplete definitions of types and forward declarations in interfaces and implementations如何处理接口和实现中类型和前向声明的不完整定义
【发布时间】:2014-10-02 16:02:11
【问题描述】:

好的,让我开始这个问题。已提出此问题,但未针对未更改 .h 文件的情况专门回答此问题,因此请不要链接到已通过说“哦,将其移至 .h 文件”来回答的问题。我目前正在上课,老师将 .h 文件交给我们并说,对此进行实施并且不要更改 .h 文件中的任何内容。我按照建议将结构等移动到我之前项目的 .h 文件中,因此我的成绩受到了很大的打击

话虽如此,让我发布一些代码并深入了解细节。

.h 文件

#ifndef _list_h
#define _list_h

typedef char *ListItemP  //a pointer to an item in the list
typedef struct List *ListP //a pointer to the List struct itself

somefunctions();

#endif

.c 文件

#include "List.h"
struct List
{
    int foo;
    ListItemP bar;
};

ListP newList()
{
    // implementation, I understand and am confident I used malloc 
    // and everything else correctly to make a new struct
}

main.c 或 tester.c 或任何你想称之为的文件,我在其中测试实现和接口(分别为 .c 和 .h)

#include <stdio.h>
#include <stlib.h>
#include "List.h"

int main()
{
     ListP n1 = newList();
     n1->foo = 5;

     return 0;
}

这些是我在我的 unix (osx) 终端上使用 gcc -O List.c main.c 编译后遇到的错误

 main.c:16:5: error: incomplete definition of type 'struct List'

 n1->foo = 5;
 ~~^

./List.h:21:16: note: forward declaration of 'struct List'

 typedef struct List *ListP;
           ^
 1 error generated.

我们将不胜感激任何帮助,如果您坚持将我链接到以前提出的问题,请指出他们在该问题中的哪个位置回答了我的问题的特定部分。也许我错过了,但我觉得我已经非常彻底地检查了这些问题。自本课程开始以来,这个问题就一直困扰着我,所以一段代码可以让我直截了当,但是我希望得到一个解释,这样我才能最终理解我做错了什么。谢谢谢谢谢谢。

【问题讨论】:

  • 您需要在 main.c 文件中包含列表 .c 文件的内容(即使用单个源文件)。如果头文件中有结构声明,则可以使用不同的列表实现文件。
  • 您应该尝试仅使用list.h 中声明的函数和类型。如果您需要测试访问实现细节的实现,请将测试代码添加到list.cc

标签: c struct forward-declaration incomplete-type


【解决方案1】:

由于只有“.c”文件知道 List 的定义,所以访问其成员的所有代码都必须存在。这是一种有效的技术,您可以强制所有其他源文件仅处理指针而不处理其成员。因此,您的测试代码应该调用在“.c”文件中实现的函数以填充它。

void
setFoo(ListP p, int foo);

int main()
{
     ListP n1 = newList();
     setFoo(n1, 5);

     return 0;
}

在定义“列表”的“.c”文件中:

void
setFoo(ListP p, int foo)
{
    p->foo = foo;
}

无论如何,'setFoo' 的原型需要对您的测试程序可见。您可能想在头文件中定义它,或者只是将其添加到测试器主体本身。

【讨论】:

    【解决方案2】:

    要访问结构中的成员字段,代码需要知道存在哪些成员字段。如果代码没有结构体定义,则不知道结构体中有哪些成员字段,编译会失败。这就是为什么结构通常在头文件中定义的原因。

    所以解决问题的简单方法是将结构List 放入list.h 头文件中。如果您不能修改头文件,则需要创建另一个包含结构定义的头文件,并将其包含在list.h 头文件之前。如果你不能这样做,那么你需要让你的程序成为一个单一的源文件。如果你连这点都做不到,那么你的问题就无法解决。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-02
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      相关资源
      最近更新 更多