链接和静态函数混淆
Linkage and static function confusion
我读到
A function with internal linkage is only visible to one compilation
unit. (...) A function declared static has internal linkage
对于 .c
文件,它有点有意义,但我想知道 header 中的静态函数会发生什么情况,它被多个 .c
文件包含但通常有一个包含守卫
我正在 this answer 阅读 header 中有关静态函数的内容,第一项提到它不会创建具有外部链接的符号,第二项提到该函数纯粹可用通过 header 文件。这不是自相矛盾吗?怎么能既有功能又没有外部符号呢?所以我做了一个小测试:
/* 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
会导致相同的行为。我有点迷路了。
阅读 here,header 文件的基本工作原理。这应该澄清你的实际问题。
简而言之:只是插入了一个 header 文件,而不是相应的 #include
指令。因此,任何声明或定义都被编译器视为您实际上 copy/pasted 将文本放入文件中。
无论如何,你应该小心header中的函数定义。这通常被认为是糟糕的风格。例如,它破坏了代码,创建了该函数的冗余副本。也不能比较函数指针(你永远不知道......)。通常最好将函数捆绑到一个库中,只用 header 中的 声明 (non-static 然后:外部链接)。然而,有时有充分的理由(没有例外)。其中之一是 inline
函数。
-静态函数是只对同一文件(更准确地说是同一翻译单元)中的其他函数可见的函数。
有关链接的详细说明,请查看这篇文章:http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html
我读到
A function with internal linkage is only visible to one compilation unit. (...) A function declared static has internal linkage
对于 .c
文件,它有点有意义,但我想知道 header 中的静态函数会发生什么情况,它被多个 .c
文件包含但通常有一个包含守卫
我正在 this answer 阅读 header 中有关静态函数的内容,第一项提到它不会创建具有外部链接的符号,第二项提到该函数纯粹可用通过 header 文件。这不是自相矛盾吗?怎么能既有功能又没有外部符号呢?所以我做了一个小测试:
/* 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
会导致相同的行为。我有点迷路了。
阅读 here,header 文件的基本工作原理。这应该澄清你的实际问题。
简而言之:只是插入了一个 header 文件,而不是相应的 #include
指令。因此,任何声明或定义都被编译器视为您实际上 copy/pasted 将文本放入文件中。
无论如何,你应该小心header中的函数定义。这通常被认为是糟糕的风格。例如,它破坏了代码,创建了该函数的冗余副本。也不能比较函数指针(你永远不知道......)。通常最好将函数捆绑到一个库中,只用 header 中的 声明 (non-static 然后:外部链接)。然而,有时有充分的理由(没有例外)。其中之一是 inline
函数。
-静态函数是只对同一文件(更准确地说是同一翻译单元)中的其他函数可见的函数。
有关链接的详细说明,请查看这篇文章:http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html