我在Geany项目中遇到了一个奇怪的问题。该项目非常简单,在同一个目录中包含3个文件:main.cfoo.hfoo.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函数。

07-28 02:53
查看更多