链接和静态功能混淆

时间:2015-06-19 01:17:58

标签: c include linkage

我读了那个

  

具有内部链接的函数仅对一个编译可见   单元。 (...)声明为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会导致相同的行为。我有点失落。

2 个答案:

答案 0 :(得分:4)

阅读here,头文件基本上如何工作。这应该澄清你的实际问题。

简单地说:只插入头文件而不是相应的#include指令。因此,编译器会将任何声明或定义视为您实际将文本复制/粘贴到文件中。

无论如何,你应该小心标题中的函数 definitions 。一般来说,这被认为是不好的风格。例如,它会破坏代码,创建该函数的冗余副本。函数指针也无法比较(你永远不会知道......)。通常最好将函数捆绑到一个库中,只需在头文件中使用声明(非静态的,然后是:外部链接)。然而,有时候有充分的理由(没有例外的规则)。其中一个是inline函数。

答案 1 :(得分:2)

-static函数是仅对同一文件中的其他函数可见的函数(更准确地说是相同的翻译单元)。

查看本文以获取有关链接的详细说明:http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html