【问题标题】:How Linkers Resolve Multiply Defined Global Symbols in C链接器如何在 C 中解析多重定义的全局符号
【发布时间】:2018-11-05 11:49:34
【问题描述】:

我的教科书上说:

“函数和初始化的全局变量得到强符号。未初始化的全局变量得到弱符号。给定一个强符号和多个弱符号,选择强符号”

所以我创建了两个文件来查看:

file1.c:

int number;

int main(int argc, char *argv[]) 
{
    printf("%d",number);
    return 0;
}

file2.c(只有一行):

int number = 2018;

我跑了gcc -Wall -o program file1.c file2.c,输出为0,在我研究链接器之前我可以理解(file1.c中的'number'已经初始化为0),但是在我研究了链接器是如何工作的之后,我开始怀疑为什么输出不是 2018,因为 file2 中的“数字”是强符号(初始化的全局变量),而 file1 中的“数字”是弱符号,所以链接器会选择值为 2018 的强符号,那么为什么链接器选择弱符号?

【问题讨论】:

  • 你用的是什么工具链?我认为这是根据标准的 UB,但我很确定大多数链接器会将 int number; 设为所谓的“通用”符号,在存在强符号的情况下,它将被强符号合并。我将迎来 2018 年的所有 tinycc、gcc 和 clang。

标签: c linker operating-system static-linking


【解决方案1】:

file1.c 中的int number; 未初始化。请注意,它是在文件范围内声明的,它是在没有初始化器的情况下声明的,并且它是在没有存储类说明符的情况下声明的(特别是没有externstatic)。然后 C 2018 6.9.2 2 说:

具有文件范围的对象的标识符声明没有初始化程序,没有存储类说明符或存储类说明符static,构成一个暂定定义。如果翻译单元包含一个或多个标识符的暂定定义,并且翻译单元不包含该标识符的外部定义,则行为与翻译单元包含该标识符的文件范围声明完全相同,复合类型为翻译单元的末尾,初始化器等于 0。

因此,file1.c 中的int number;int number = 0; 相同。已初始化。

您引用的文本的一个问题是它使用该链接器的术语来描述链接器,这与 C 标准使用的术语不同。 C 标准没有任何“全局”变量或“强”或“弱”符号。

【讨论】:

  • 不是整数;在全局范围内声明?
  • @nicomp:C 标准没有任何“全局范围”的范围。有文件范围和外部链接。在任何块或参数列表之外声明的标识符具有文件范围。
  • @EricPostpischil,但是如果 file1.c 中的 int number 与 int number = 0 相同,那么我们有两个强符号,链接器在遇到多个强符号时不应该抛出错误变量,我的意思是“'number'的多重定义”的错误
  • @amjad:根据 C 2018 6.9 5,整个程序中外部对象的定义不得超过一个。根据 4 2,违反“应”具有 C 标准未定义的行为。因此允许 C 实现在这里做任何事情,包括完成链接。在我的情况下(带有 Xcode 9.4.1 的 macOS 10.13.6),“2018”被打印出来,我相信这些工具使用的是一个长期建立的 Unix 行为,其中显式初始化的对象占主导地位(实际上,Unix 通过定义扩展了 C C 标准未定义的行为)。您应该说明您正在使用的工具。
【解决方案2】:

file2.c 中的number 是全局的,但仍仅限于该文件的本地范围。如果您希望 file1.c 使用来自 file2.c 的 number,您需要将其标记为 extern,如下所示:

extern int number;

int main(int argc, char *argv[]) 
{
    printf("%d",number);
    return 0;
}

【讨论】:

  • 抱歉没看懂,如果全局变量不带static关键字,那么它是全局范围的,可以被程序访问,不然为什么需要static关键字来限制访问其他模块?
  • C 标准不使用“全局”来表示范围或链接。您的意思可能是 file2.c 中的number 具有外部链接但文件范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-10
  • 2017-06-14
相关资源
最近更新 更多