【问题标题】:Linkage and static function confusion联动与静态功能混淆
【发布时间】:2015-06-19 01:17:57
【问题描述】:

我读到了

具有内部链接的函数仅对一个编译可见 单元。 (...) 声明为静态的函数具有内部链接

对于.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 会导致相同的行为。我有点迷路了。

【问题讨论】:

  • 1.h 在任何特定的翻译单元中都包含一次。 IE。在任何一个 .C 文件中。您的代码有 2 个 .c 文件,每个 .c 文件中都包含一个

标签: c include linkage


【解决方案1】:

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

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

无论如何,您应该小心标题中的函数定义。这通常被认为是不好的风格。例如,它破坏了代码,创建了该函数的冗余副本。函数指针也不能比较(你永远不知道......)。通常最好将函数捆绑到一个仅在标头中使用 declarations 的库中(非静态然后:外部链接)。然而,有时有很好的理由(没有例外)。其中之一是inline 函数。

【讨论】:

    【解决方案2】:

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

    链接的详细解释请查看这篇文章:http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html

    【讨论】:

    • 这正是引用所说的:“具有内部链接的函数仅对一个编译单元可见。(...)声明为静态的函数具有内部链接”。
    猜你喜欢
    • 1970-01-01
    • 2011-01-15
    • 2012-01-05
    • 2013-10-24
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多