C typedef:参数具有不完整的类型

3

GCC 3.4.5(MinGW版本)会在以下C代码的第2行产生警告:参数具有不完整类型:

struct s;
typedef void (* func_t)(struct s _this);
struct s { func_t method; int dummy_member; };

有没有一种方法可以修复这个问题(或者至少隐藏警告),而不需要更改方法参数的签名为(struct s *)?

注意:
为什么这样的东西会有用:我目前正在尝试使用面向对象的框架;'method'是一个调度表中的条目,由于框架的特定设计,通过值传递'_this'而不是通过引用传递是有意义的(通常是通过引用传递)...


哪个版本的GCC?那个精确的代码片段(再加上一个main函数)在Ubuntu附带的GCC(版本为4.3.2)中没有产生任何警告。是否还有其他原因导致出现警告? - Sean
我目前被困在MinGW版本的gcc上,它是3.4.5(?)。但很高兴知道问题可能最终会消失... - Christoph
GCC 3.4.6在-Wall下报错;GCC 4.3.2不会报错- Solaris 10。 - Jonathan Leffler
你会如何使用这个结构体/函数?这是一个最大程度简化的例子(通常是一件好事 - 尽管你可能在最小化方面走得太远了),还是一个虚构的测试用例?我无法看出如何从这样的结构体或函数中获得有用的结果。 - Jonathan Leffler
为什么按值传递参数是有意义的? - Sean
5个回答

1

1

你不能轻易地这样做 - 根据C99标准,第6.7.5.3节,第4段:

调整后,在函数声明符中的参数类型列表中的参数不得具有不完整的类型,该函数是该函数定义的一部分。

因此,您的选择是将函数接受指向结构体的指针,或者接受指向稍微不同类型的函数的指针,例如接受未指定参数的函数:

typedef void (* func_t)(struct s*);  // Pointer to struct
typedef void (* func_t)(void *);     // Eww - this is inferior to above option in every way
typedef void (* func_t)();           // Unspecified parameters

但是那个函数没有定义,只有声明吗? - Jonathan Leffler
谢谢。你上次的建议确实做到了我想要的,但是我会失去所有类型信息(并在使用-Wstrict-prototypes编译时收到警告) - 所以我很可能会坚持使用我得到的版本... - Christoph
我认为乔纳森是正确的。在C语言中可能无效(我不确定,我只知道在C++中它是有效的),但你展示给我们的语句并没有使其无效。在他的代码中,函数声明符不是定义的一部分,它只是在声明函数。 - Johannes Schaub - litb

0

嗯,我知道。但是提问者问的是如何隐藏警告,我只是指出了如何做到。对于回答他问题的这一部分而被踩似乎有点不公平... - Tim

0

警告似乎是当前MinGW版本的gcc中的一个错误。与Adam所说的相反,它确实是有效的C99 - 第6.7.5.3节,第12段明确允许此操作:

如果函数声明符不是该函数的定义的一部分,则参数可以具有不完整的类型,并且可以在其声明符序列中使用[*]符号来指定可变长度数组类型。

似乎没有办法指示(这个版本的)gcc不打印此警告 - 至少我找不到一个有效的开关 - 所以我现在只是忽略它。


-1
你想使用函数指针来调用它。为什么不使用 void 指针呢?
typedef void (*func_t)(void*);

你可能也可以传递一个松散类型的函数指针;我手头上没有编译器。
typedef void (*func_t)(void (*)());

你希望使用函数指针来调用它。实际上,我并不需要这样做。结构体s还包含其他成员 - 我马上会澄清问题…… - Christoph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接