为了账号安全,请及时绑定邮箱和手机立即绑定

奇怪的编译器警告C:警告:参数列表内声明了'struct'

奇怪的编译器警告C:警告:参数列表内声明了'struct'

C
达令说 2019-12-02 13:53:25
我刚刚在C语言中发现了一个奇怪的问题,令人感到困惑。在C语言中,可以在结构体声明之前使用它的指针。这是一个非常有用的功能,因为在处理指向它的指针时,声明是无关紧要的。但是,我只是发现一个极端的情况(令人惊讶地),这是不正确的,而且我无法真正解释原因。在我看来,这似乎是语言设计中的一个错误。采取以下代码:#include <stdio.h>#include <stdlib.h>typedef void (*a)(struct lol* etc);void a2(struct lol* etc) {}int main(void) {        return 0;}给出:foo.c:6:26: warning: ‘struct lol’ declared inside parameter list [enabled by default]foo.c:6:26: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]foo.c:8:16: warning: ‘struct lol’ declared inside parameter list [enabled by default]为了解决这个问题,我们可以简单地做到这一点:#include <stdio.h>#include <stdlib.h>struct lol* wut;typedef void (*a)(struct lol* etc);void a2(struct lol* etc) {}int main(void) {        return 0;}无法解释的问题现在由于无法解释的原因而消失了。为什么?请注意,这个问题是关于语言C的行为(或者可能是gcc和clang的编译器行为),而不是我粘贴的特定示例。编辑:我不会接受“声明的顺序很重要”作为答案,除非您也解释了为什么C会在函数参数列表中第一次警告不要使用struct指针,但允许在任何其他上下文中使用它。为什么那可能是个问题?
查看完整描述

3 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

这是因为,在第一个示例中,该结构先前未定义,因此编译器尝试将对该结构的第一个引用视为定义。

通常,C是声明顺序很重要的语言。您使用的所有内容均应事先以某种能力进行适当声明,以便编译器可以在其他上下文中引用它时对其进行推理。

这不是语言设计中的错误或错误。相反,我认为这是为了简化第一个C编译器的实现而做出的选择。前向声明使编译器可以一次通过串行转换源代码(只要知道一些信息(例如大小和偏移量))。如果不是这种情况,则编译器只要遇到无法识别的标识符,便能够在程序中来回移动,从而要求其代码发射循环更加复杂。


查看完整回答
反对 回复 2019-12-02
?
慕妹3146593

TA贡献1820条经验 获得超9个赞

编译器警告你一个向前声明的struct lol。C允许您执行以下操作:


struct lol;     /* forward declaration, the size and members of

                   struct lol are unknown */

这在定义自引用结构时最常用,但是在定义从未在头文件中定义的私有结构时也很有用。由于存在后者,因此可以声明接收或返回指向不完整结构的指针的函数:


void foo(struct lol *x);

但是,像您一样,仅在函数声明中使用未声明的结构,将被解释为局部不完整声明,struct lol其范围受函数约束。这种解释是由C标准强制执行的,但是它没有用(无法构造struct lol传递给函数的方法),并且几乎肯定不是程序员想要的,因此编译器警告。


查看完整回答
反对 回复 2019-12-02
  • 3 回答
  • 0 关注
  • 1572 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信