我有这段代码:
int foo1(void); //line a
int foo2(void) {
return foo1();
}
int foo1(void) { //line b
return 99;
}
如果我想声明函数foo1是静态的,我应该将关键字static放在第a行还是第b行?有什么不同吗?
另外说我在上面文件中使用foo1的另一个文件中有以下代码:
static int foo1(void);
int main(void) {
return foo1();
}
代码仍然编译并按预期工作,尽管我在声明行中放置了静态。但它给出了一个警告说'foo1'已经使用但从未定义 - 如果没有定义,为什么代码仍然有用?
编辑: 对不起,我没说清楚,对于第二个问题,foo1在第一个文件中,它的定义未被声明为静态,但我在第二个文件中将其声明为静态。
答案 0 :(得分:2)
在第一种情况下,您需要将static
放在第a和b行。 C中的静态函数具有内部链接,这意味着它们仅在同一文件中可见。因此,对于声明和定义,您需要放置static
以便编译器知道该函数具有内部链接。如果你没有将static
放在第一行,你将会遇到一些编译错误。
在第二种情况下,由于foo1
是静态函数,因此必须在与main
相同的文件中定义它。你只提出一个没有实际定义的前瞻声明。即使它编译得很好,程序也不会链接,因为foo1
没有定义。
答案 1 :(得分:1)
此上下文中的static
关键字指定不导出foo1
,因此特定的foo1
只能在同一个编译模块中定义,因此当它不是时会发出警告。 (如果没有static
,代码就是正确的,假设您要将foo1
与其他文件相关联。)
至于为什么它可以正常工作,我的猜测是编译器依赖于寻找外部函数,它从你的其他文件中找到,但我认为符合标准的编译器在这里给出错误是合理的。
答案 2 :(得分:0)
在C static中,函数意味着内部链接和仅在文件范围内使用该函数。 有趣的是,编译器的行为方式不同:
小组1:
GCC和clang要求static
在声明(行a)中,在定义(行b)中它可以省略。
在MS VC中,您可以将static
置于声明或仅在定义中,这使得foo1()成为静态。
Snippet 2(main.c中的静态foo1,其他文件中的非静态声明): GCC编译静态声明而没有定义。 clang编译但是发出警告。 (两者都链接。) MS VS根本不编译第二个片段,给出错误C2129。
因此,为了清楚起见,将static
放在声明和定义中,并在声明它们的文件中定义静态函数。如果需要,在使用函数之前提出声明。
总的来说,似乎clang具有更好的诊断功能。
“......如果没有定义,为什么代码仍然有效?”
在C语言中,不需要在函数调用之前声明原型。该定义不是在连接步骤中找到的。