“参数有不完整类型”警告

时间:2011-05-13 19:27:31

标签: c incomplete-type

我在C文件中有这个:

struct T
{
    int foo;
};

C文件包含一个带有这些行的h文件:

typedef struct T T;
void listInsertFirst(T data, int key, LinkedList* ListToInsertTo);

函数listInsertFirst是我收到警告的函数。我该如何解决?

5 个答案:

答案 0 :(得分:2)

当您包含头文件时,编译器知道T是一个未知大小的结构,并且listInsertFirst想要一个作为其第一个参数。但编译器无法安排对listInsertFirst的调用,因为它不知道要在T data参数的堆栈上推送多少字节,T的大小仅在文件内部已知其中listInsertFirst已定义。

最佳解决方案是更改listInsertFirst以将T*作为其第一个参数,以便您的头文件可以这样说:

extern void listInsertFirst(T *data, int key, LinkedList* ListToInsertTo);

然后你得到一个T数据类型的不透明指针,因为所有指针都是相同的大小(至少在现代世界中),编译器会在调用{{1时'时知道如何构建堆栈}}

答案 1 :(得分:2)

正如我们在评论中发现的那样,问题是struct T的定义发生在标题中T的定义之后。你真的在这里倒退了。标题应该是定义所有类型和函数原型,你的C文件应该使用它们。

您要做的是改变插入函数的签名,以接收指向数据的指针和数据的大小。然后,您可以为数据分配一些内存,复制并存储它。您不需要特定类型,只需将其声明为void *

void listInsertFirst(void *data, size_t data_size, int key, LinkedList* ListToInsertTo);

然后调用者会做这样的事情:

struct T { int foo; };
struct T x = { ... };
int someKey = ...;
LinkedList *someList = ...;
listInsertFirst(&x, sizeof x, someKey, someList);

答案 2 :(得分:0)

你确定它是问题的第一个参数吗?请务必尝试暂时将参数类型从T更改为int。更有可能的是,第三个参数实际上就是问题。

许多编制者都没有很好地指出这类问题。

答案 3 :(得分:0)

尝试在typedef之前将结构定义移动到h文件。

答案 4 :(得分:0)

  1. 在标头中定义struct T,而不是在.c文件中定义;
  2. 为结构和typedef选择不同的名称。