在C中,有没有一种方法可以将静态原型和公共原型放在同一个头文件中?
当我在头文件中将public和静态原型混合在一起时,编译器总是抱怨 假设我有main.h头,函数a有一个静态原型,函数b有一个正常原型。然后我想在两个.c文件中包含头文件,即main.c和other.c。在main.c中,在调用任何原型之前,我需要一个include函数 主要条款h:在C中,有没有一种方法可以将静态原型和公共原型放在同一个头文件中?,c,static,header,C,Static,Header,当我在头文件中将public和静态原型混合在一起时,编译器总是抱怨 假设我有main.h头,函数a有一个静态原型,函数b有一个正常原型。然后我想在两个.c文件中包含头文件,即main.c和other.c。在main.c中,在调用任何原型之前,我需要一个include函数 主要条款h: static int a(void); int b(void); 主要条款c: #include "main.h" void main(){ a(); } static int a(void){ /*
static int a(void);
int b(void);
主要条款c:
#include "main.h"
void main(){
a();
}
static int a(void){
/* do stuff */
}
int b(void){
/* do stuff */
}
其他.c:
#include "main.h"
b();
除了将头文件拆分为一个单独的头文件(专用于静态原型)和一个单独的头文件(专用于公共原型)这一显而易见的解决方案之外,最好的做法是什么呢?如果在
main.h
中有b()
的声明,为什么在包含它的other.c
中还需要它呢?除此之外,一切都很好,看不出任何问题
关于“普通”函数,需要记住的重要一点是,同一函数的所有正向声明(b()
,在本例中)必须匹配,否则您将遇到问题(链接错误、编译器错误,以及其他错误)。在你的情况下,他们不匹配
当然,除非b()
是对函数的实际调用,但至少在您发布的代码中,它超出了任何范围,因此被视为转发声明
对于
静态
转发声明,它们限制了编译单元对函数的可见性。因此,在other.c
中调用a()
将不会执行main.c
中实现的a()
。这就是C中的static
的全部要点。在头中包含静态原型是没有意义的,原因是静态函数具有文件作用域,因此外部的任何模块都无法访问这些函数
相反,我建议您只将静态原型放在文件顶部的.c文件中,与它们定义的文件相同。您不要将静态函数声明放在头文件中。因为它们是定义它们的
.c
文件的本地文件,所以从头文件导出它们是没有意义的
您可以做两件事:
a()的定义移到main上方)
a()
的声明移动到main.c
的顶部如果要在多个翻译单元中使用该函数,则可以在头文件中定义静态函数。如果您有一个支持C99的成熟编译器,那么它可以是内联的,而不是静态的。如果您想要定义的“静态”函数足够短或足够便宜,您最好将其定义为静态内联的,并将其定义与其主体(不仅仅是其声明)放在一起在*.h头文件中。为什么在头文件中需要静态函数的原型?另外,
void main()
?如果你不在嵌入式系统上工作,你需要做一些解释…@Chris我知道它应该是int。我只是想让代码尽可能小,这样我就会得到一个答案:)我很感激你努力不转储代码,但没有人会因为返回0而感到不快代码>;)@克里斯:希望没有人会因为intmain()
而不返回0代码>其中之一,这是最短的。即使是那些受原始编译器困扰的人,至少也应该听说过C99;-)3.在头文件中定义静态函数。在本例中,a
仅在一个TU中使用,因此它可能根本不应该在头中(2是正确的)。但是,如果您真的要在多个TU中使用a
,那么它应该在头中定义,并且可以是inline
,而不是static
,前提是您有一个支持C99的成熟编译器。