我读了那个
具有内部链接的函数仅对一个编译可见 单元。 (...)声明为static的函数具有内部链接
对于.c
文件,它的排序是有意义的,但我想知道标题中的静态函数会发生什么,它被多个.c
文件包含但通常有一个包含保护。
我正在阅读this answer关于标题中的静态函数,第一项提到它不会创建带有外部链接的符号,第二项提到该函数完全可以通过头文件获得。这不矛盾吗?该功能如何可用,同时没有外部符号?所以我做了一点测试:
/* 1.h */
#ifndef ONE_H
#define ONE_H
#include <stdio.h>
static void foo() {
printf("foo from 1.h %p\n", foo);
return;
}
void bar();
#endif
/* 1.c */
#include "1.h"
#include <stdio.h>
void bar() {
printf("foo,bar from 1.c %p,%p\n", foo, bar);
foo();
}
/* 2.c */
#include "1.h"
#include <stdio.h>
int main() {
printf("foo,bar from main %p,%p\n", foo, bar);
foo();
bar();
return 0;
}
...
debian@pc:~ gcc 2.c 1.c
debian@pc:~ ./a.out
foo,bar from main 0x400506,0x400574
foo from 1.h 0x400506
foo,bar from 1.c 0x400559,0x400574
foo from 1.h 0x400559
正如预期的那样bar
在所有文件中都是相同的,但不应该foo
也是如此?是不是只包含1.h
一次?将inline
添加到foo
会导致相同的行为。我有点失落。
答案 0 :(得分:4)
阅读here,头文件基本上如何工作。这应该澄清你的实际问题。
简单地说:只插入头文件而不是相应的#include
指令。因此,编译器会将任何声明或定义视为您实际将文本复制/粘贴到文件中。
无论如何,你应该小心标题中的函数 definitions 。一般来说,这被认为是不好的风格。例如,它会破坏代码,创建该函数的冗余副本。函数指针也无法比较(你永远不会知道......)。通常最好将函数捆绑到一个库中,只需在头文件中使用声明(非静态的,然后是:外部链接)。然而,有时候有充分的理由(没有例外的规则)。其中一个是inline
函数。
答案 1 :(得分:2)
-static函数是仅对同一文件中的其他函数可见的函数(更准确地说是相同的翻译单元)。
查看本文以获取有关链接的详细说明:http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html