我在Geany项目中遇到了一个奇怪的问题。该项目非常简单,在同一个目录中包含3个文件:main.c
,foo.h
和foo.c
。
编译器错误:
In file included from main.c:1:0:
foo.h:4:12: warning: ‘bar’ used but never defined
static int bar(void);
^
/tmp/cc0zCvOX.o: In function `main':
main.c:(.text+0x12): undefined reference to `bar'
Compilation failed.
collect2: error: ld returned 1 exit status
怎么了?
main.c:
#include "foo.h"
int main(int argv, char* argc[])
{
bar();
return 0;
}
foo.h:
#ifndef _FOO_H_
#define _FOO_H_
static int bar(void);
#endif // _FOO_H_
foo.c:
#include "foo.h"
#include <stdio.h>
static int bar(void)
{
printf("Hello World\n");
return 1;
}
最佳答案
如果将函数声明为static
,则该函数在文件范围内,这意味着该函数的范围仅限于转换单元(在这种情况下为源文件)。同一编译单元中存在的其他函数可以调用这些函数,但是编译单元外部的任何函数都不能看到该定义(存在)或调用该函数。
相关:从C11
标准文档的章节,标识符的链接
如果对象或函数的文件作用域标识符的声明包含存储类说明符static
,则该标识符具有内部链接。(30)
还有脚注(30),
仅当函数声明在文件范围内时,它才能包含存储类说明符static
。
解决方案:删除函数定义和声明中的static
。
FWIW,将static
函数的前向声明放在头文件中没有太大意义。无论如何,不能从其他源文件中调用static
函数。