我在C文件中有这个:
struct T
{
int foo;
};
C文件包含一个带有这些行的h文件:
typedef struct T T;
void listInsertFirst(T data, int key, LinkedList* ListToInsertTo);
函数listInsertFirst
是我收到警告的函数。我该如何解决?
答案 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)
struct T
,而不是在.c文件中定义;