我刚刚在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编译器的实现而做出的选择。前向声明使编译器可以一次通过串行转换源代码(只要知道一些信息(例如大小和偏移量))。如果不是这种情况,则编译器只要遇到无法识别的标识符,便能够在程序中来回移动,从而要求其代码发射循环更加复杂。
慕妹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传递给函数的方法),并且几乎肯定不是程序员想要的,因此编译器警告。
- 3 回答
- 0 关注
- 1572 浏览
添加回答
举报
0/150
提交
取消